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

Injecting factory using Autofac vs. delegate factories

我是 Autofac 的新用户。

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

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

谁的解决方案效果很好。

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

看起来,如果您使用委托工厂,那么您实际上根本不需要编写工厂class?

这是我当前工厂的截图 class:

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 根本不接受构造函数参数。

这是我在 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?

很好奇

谢谢

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

在你的情况下你需要一个工厂。您的工厂可能还依赖于 IIndex<String, IProvideExternalUserInformation> 而不是依赖于 IComponentContext,这可以避免 scope & co.

的问题

您的 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>();