C# Ninject和x27的单位等价物;使用CQRS的s Bind.tome方法

C# Ninject和x27的单位等价物;使用CQRS的s Bind.tome方法,c#,ninject,unity-container,ioc-container,cqrs,C#,Ninject,Unity Container,Ioc Container,Cqrs,我正在关注CQS tuturiol,它使用Ninject 我目前正在使用Unity,并尝试将其转换为: Bind<IQueryFactory>().ToMethod(t => new QueryFactory(x => Container.Current.Resolve(x))).InTransientScope(); Bind().ToMethod(t=>newqueryfactory(x=>Container.Current.Resolve(x)).InTr

我正在关注CQS tuturiol,它使用Ninject

我目前正在使用Unity,并尝试将其转换为:

    Bind<IQueryFactory>().ToMethod(t => new QueryFactory(x => Container.Current.Resolve(x))).InTransientScope();
Bind().ToMethod(t=>newqueryfactory(x=>Container.Current.Resolve(x)).InTransientScope();
我的查询工厂如下所示:

public class QueryFactory : IQueryFactory
{
    private readonly Func<Type, object> _resolveCallback;

    public QueryFactory(Func<Type, object> resolveCallback)
    {
        _resolveCallback = resolveCallback;
    }

    public T ResolveQuery<T>()
        where T : class, IQuery
    {
        return _resolveCallback(typeof (T)) as T;
    }
}
公共类查询工厂:IQueryFactory
{
私有只读函数resolveCallback;
公共查询工厂(Func resolveCallback)
{
_resolveCallback=resolveCallback;
}
公共解析查询()
T:课堂,伊奎里
{
将_(typeof(T))返回为T;
}
}

我尝试了
container.RegisterType(t=>newinjectionfactory(u=>u.Resolve(u))但那不起作用。

你会认为注射剂工厂将是一条出路。这包括:

container.RegisterType<IQueryFactory>(new ContainerControlledLifetimeManager(),
    new InjectionFactory((c, x, o) => new QueryFactory(t => c.Resolve(x))));
container.RegisterType(新ContainerControlledLifetimeManager(),
新的注入工厂((c,x,o)=>newqueryfactory(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;
    }
公共类查询工厂:IQueryFactory
{
专用只读IDictionary\u factoryQueries;
公共查询工厂(IDictionary factoryQueries)
{
这是.\u factoryQueries=factoryQueries;
}
public T ResolveQuery(),其中T:class,IQuery
{
将此返回。_factoryQueries[typeof(T)]()作为T;
}
基本上,
Func resolveCallback
被替换为包含Func的IDictionary,用于创建所有支持的IQuery类型

接下来注册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();
IUnityContainer container=newunitycontainer();
//注册所有IQuery的
container.RegisterType();
container.RegisterType();
IDictionary factoryQueries=新字典()
{
{typeof(IActiveUsersQuery),()=>container.Resolve()},
{typeof(IUserByEmailQuery),()=>container.Resolve()},
};
//寄存器映射
container.RegisterInstance(factoryQueries);
container.RegisterType();
var factory=container.Resolve();
factory.ResolveQuery().Execute();
factory.ResolveQuery().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;
    }
}
公共类查询工厂:IQueryFactory
{
专用只读IUnityContainer容器;
公共查询工厂(IUnityContainer容器)
{
this.container=容器;
}
公共解析查询()
T:课堂,伊奎里
{
将此.container.Resolve(typeof(T))返回为T;
}
}
但是,有些人会反对让工厂依赖于容器实现


另一种方法是摆脱工厂方法并直接注入查询;这会使依赖性变得明显,但我可以看到这样一种场景,即您希望根据命令类型动态获取查询。此外,我还看到了命令和查询之间的关系,这些关系可以通过中解析的开放泛型来处理合成根。

那篇文章给出的查询模型是有限的,因为
IQuery
接口不是通用的。我建议使用一个解释过的模型。