C# 使用Unity(容器抽象)定义自定义autofacs?

C# 使用Unity(容器抽象)定义自定义autofacs?,c#,ninject,unity-container,C#,Ninject,Unity Container,在Ninject中你可以做到 kernel.Bind(typeof(Func<,>)).ToMethod(CreateFunc).When(VerifyFactoryFunction); public MyConstructor(Func<Type, IResult> factory) { this.result = factory(typeof(SomeType)); } 团结起来,这可能吗?我采用了这种扩展方法 public static void Regi

在Ninject中你可以做到

kernel.Bind(typeof(Func<,>)).ToMethod(CreateFunc).When(VerifyFactoryFunction);
public MyConstructor(Func<Type, IResult> factory) {
   this.result = factory(typeof(SomeType));
}
团结起来,这可能吗?我采用了这种扩展方法

public static void RegisterContainerAbstraction<TTo>(this IUnityContainer self)
{
    self.RegisterInstance<Func<Type, TTo>>(t => (TTo)self.Resolve(t));
}
publicstaticvoidregistercontainerastraction(此IUnityContainer自身)
{
self.RegisterInstance(t=>(TTo)self.Resolve(t));
}
您需要为所有要抽象容器的类型调用它,例如

container.RegisterContainerAbstraction<IResult>();
container.RegisterContainerAbstraction();

Ninject允许的是一种特殊功能,这更像是一种功能性方法。NET中的DI库默认采用更面向对象的方法,这意味着对创建和自动连接类的支持通常相当好,而对函数的创建和转换的支持却很差

因此,在Unity中,没有任何东西可以让您这样做,但通过创建自定义接口和实现,可以轻松解决这一问题:

// Abstraction: Part of your core library
public interface IFactory<TResult>
{
    TResult Create(Type type);
}

// Implementation: Part of your composition root
private sealed CreateFuncFactory<TResult> : IFactory<TResult>
{
    // Since we're in the Composition Root, its okay to depend
    // on the container here. See: https://bit.ly/1mdaLYG 
    private readonly IUnityContainer container;
    public CreateFuncFactory(IUnityContainer container) {
        this.container = container;
    }

    public TResult Create(Type type) {
        return (TResult)container.Resolve(type);
    }
}
//抽象:核心库的一部分
公共接口工厂
{
TResult创建(类型);
}
//实现:组成根目录的一部分
私人工厂:IFactory
{
//因为我们在合成根中,所以可以依赖它
//在此处的容器上。请参见:https://bit.ly/1mdaLYG 
专用只读IUnityContainer容器;
公共CreateFuncFactory(IUnityContainer容器){
this.container=容器;
}
公共TResult创建(类型){
返回(TResult)容器。解析(类型);
}
}
您可以按如下方式在Unity中注册:

container.RegisterType(typeof(IFactory<>), typeof(CreateFuncFactory<>));
container.RegisterType(typeof(IFactory)、typeof(CreateFuncFactory));

然而,如果您正确地应用依赖项注入,那么工厂抽象的需求就会大大减少。它们仍然有用,但在应用程序中可能只需要一手资料。因此,在这方面,与其有一个通用的
Func
IFactory
抽象,不如指定特定的工厂。这使事情变得更加明显,因为您应该有一些工厂,这不会产生大量样板代码。

是的,我们只在主API中使用它,比如命令/查询处理程序和其他接近DI入口点的东西。在一个巨大的企业系统中,你仍然会有一些类似的工厂。同样在一个基于插件的系统中,很多类型的调用都完成了,能够抽象容器也很好。下面是我使用ninject的一个开源项目的示例@安德斯:没错,你们会有一些这样的工厂。不多。工厂的广泛使用通常是因为害怕让容器管理对象的生命周期。是的,但我仍然觉得我不想让容器离引导程序太远(您配置绑定的地方)。即使它只是一些地方。使用DI,您可以将容器从Unity替换为Ninject或诸如此类的东西,并且在Boostrapper被移植到新的DI@Anders:我故意将该实现设置为私有,因为该关键字仅对嵌套类有效。这样你就可以把它放在同一个班级里。
container.RegisterType(typeof(IFactory<>), typeof(CreateFuncFactory<>));