使用Autofac与委托工厂注入工厂

时间:2016-08-06 18:39:43

标签: dependency-injection delegates autofac factory

我是Autofac的新用户。

我有一个工厂需要根据工厂方法的输入创​​建一个不同的类,但只有一个需要创建的类具有其他依赖项。

我找到了这个答案: Autofac Binding at Runtime

其解决方案运作良好。

然后我开始阅读Autofac的代表工厂(http://docs.autofac.org/en/latest/advanced/delegate-factories.html)...现在我很困惑。

看来,如果您使用委托工厂,那么您根本不需要编写工厂类?

这是我当前工厂类的剪辑:

public class ExternalUserInformationProviderFactory : IExternalUserInformationProviderFactory
{
    private readonly IComponentContext autofacContainer;

    public ExternalUserInformationProviderFactory(IComponentContext autofacContainer)
    {
        this.autofacContainer = autofacContainer;
    }

    public IProvideExternalUserInformation GetExternalUserInformationProvider(string loginProvider)
    {
        switch (loginProvider)
        {
            case "Google":
                return autofacContainer.Resolve<GoogleExternalUserInformationProvider>();
            case "Twitter":
                return autofacContainer.Resolve<TwitterExternalUserInformationProvider>();
        }
        return null;
    }
}

在此示例中,TwitterExternalUserInformationProvider在其构造函数中采用依赖项:

public class TwitterExternalUserInformationProvider : IProvideExternalUserInformation
{
    private readonly ITwitterRepository twitterRepository;

    public TwitterExternalUserInformationProvider(ITwitterRepository twitterRepository)
    {
        this.twitterRepository = twitterRepository;
    }
}

并且GoogleExternalUserInformationProvider根本不接受构造函数args。

这是我如何将这个工厂连接到Startup.cs(我正在使用asp.net核心):

var containerBuilder = new ContainerBuilder();
containerBuilder.Register<IExternalUserInformationProviderFactory>(c => new ExternalUserInformationProviderFactory(c.Resolve<IComponentContext>()));
containerBuilder.RegisterType<TwitterExternalUserInformationProvider>();
containerBuilder.RegisterType<GoogleExternalUserInformationProvider>();

Autofac非常智能,可以为我解决ITwitterRepository依赖关系,这非常酷。

基于当前的实现,我是否可以使用委托工厂并完全摆脱ExternalUserInformationProviderFactory?

我很好奇。

由于

1 个答案:

答案 0 :(得分:1)

委托工厂不会在服务的两个实现之间进行选择,它只会根据其依赖关系创建一个组件。

在您的情况下,您需要一家工厂。您的工厂可能还会依赖IComponentContext而不是依赖IIndex<String, IProvideExternalUserInformation>,这可能会避免问题范围和问题。共

您的ExternalUserInformationProviderFactory可能如下所示:

public class ExternalUserInformationProviderFactory : IExternalUserInformationProviderFactory
{
    public ExternalUserInformationProviderFactory(IIndex<String, IProvideExternalUserInformation> providers)
    {
        this._providers = providers;
    }

    private readonly IIndex<String, IProvideExternalUserInformation> _providers; 


    public IProvideExternalUserInformation GetExternalUserInformationProvider(String loginProvider)
    {
        IProvideExternalUserInformation provider;
        if (!this._providers.TryGetValue(loginProvider, out provider))
        {
            throw new Exception("boom"); 
        }
        return provider; 
    }
}

和您的注册:

builder.RegisterType<TwitterExternalUserInformationProvider>()
       .Named<IProvideExternalUserInformation>("twitter"); 
builder.RegisterType<GoogleExternalUserInformationProvider>()
       .Named<IProvideExternalUserInformation>("google"); 
builder.RegisterType<ExternalUserInformationProviderFactory>()
       .As<IExternalUserInformationProviderFactory>();