你会认为一个InjectionFactory将是一条路。这将编译:
container.RegisterType<IQueryFactory>(new ContainerControlledLifetimeManager(),
new InjectionFactory((c, x, o) => new QueryFactory(t => c.Resolve(x))));
的问题是,X型总是IQueryFactory这样就不会得到你想要的结果,这是返回一个IQUERY。
不幸的是,我不认为目前的设计很适合Unity。
但是,稍作修改就可以让工厂运作。有几种不同的方法可以做到这一点(例如,您可以在工厂注入容器并从那里解析),但在本例中,我将使用字典。
首先我们改变了工厂的定义:
public class QueryFactory : IQueryFactory
{
private readonly IDictionary<Type, Func<IQuery>> _factoryQueries;
public QueryFactory(IDictionary<Type, Func<IQuery>> factoryQueries)
{
this._factoryQueries = factoryQueries;
}
public T ResolveQuery<T>() where T : class, IQuery
{
return this._factoryQueries[typeof(T)]() as T;
}
基本上,Func<Type, object> resolveCallback
被交换包含用于创建所有支持IQUERY类型funcs中一个IDictionary。
接着注册的IDictionary和IQueryFactory:
IUnityContainer container = new UnityContainer();
// Register all IQuery's
container.RegisterType<IActiveUsersQuery, ActiveUsersQuery>();
container.RegisterType<IUserByEmailQuery, UserByEmailQuery>();
IDictionary<Type, Func<IQuery>> factoryQueries = new Dictionary<Type, Func<IQuery>>()
{
{ typeof(IActiveUsersQuery),() => container.Resolve<IActiveUsersQuery>() },
{ typeof(IUserByEmailQuery),() => container.Resolve<IUserByEmailQuery>() },
};
// Register mapping
container.RegisterInstance<IDictionary<Type, Func<IQuery>>>(factoryQueries);
container.RegisterType<IQueryFactory, QueryFactory>();
var factory = container.Resolve<IQueryFactory>();
factory.ResolveQuery<IActiveUsersQuery>().Execute();
factory.ResolveQuery<IActiveUsersQuery>().Execute();
如所提到的,更简单的QueryFactory办法,需要在容器上的依赖关系是:
public class QueryFactory : IQueryFactory
{
private readonly IUnityContainer container;
public QueryFactory(IUnityContainer container)
{
this.container = container;
}
public T ResolveQuery<T>()
where T : class, IQuery
{
return this.container.Resolve(typeof(T)) as T;
}
}
然而,有些人会反对具有工厂依赖于容器的实现。
另一种方法是摆脱工厂方法并直接注入查询;这会使依赖关系变得明显,但我可以看到您希望根据命令类型动态获取查询的场景。另外,我已经看到了命令和查询之间的关系,这些关系可以通过组合根中解决的开放泛型来处理。
该文章给出的查询模型是有限制的,因为'IQuery'接口不是通用的。我会建议一个模型,在[这里]解释(https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92)。 – Steven