【问题标题】:Use factory to resolve dependencies使用工厂解决依赖关系
【发布时间】:2016-03-12 10:34:15
【问题描述】:

我们有一个带有 autofac 的网络解决方案。现在我们想在 Windows 服务/控制台应用程序中重用东西,其中只有当消息来自企业总线时才可用。

我有以下服务可以重复使用

public SettingsService : ISettingsService {
    public readonly ITenantIdentifer _tenantIdentifier
    public SettingsService (ITenantIdentifier tenantIdentifier) {
       this._tenantIdentifier =tenantIdentifier; 
    }
    // do other stuff
}

当前的工作设置

网络上下文的ITenantIdentifier 只是使用builder.RegisterType<WebTenantIdentifier>().As<ITenantIdentifier>(); 为网络应用程序注册。
一切都很好。

我们的企业总线

在消息可用之前,企业总线无法解析ITenantIdentifier。所以我们创建了一个MessageTenantIdentifier 并注册了一个工厂。

 public class MessageTenantIdentifier : ITenantIdentifier
 {
    public delegate MessageTenantIdentifier Factory(int tenantId);
public MessageTenantIdentifier(int tenantId, IOtherDependency stuff)
    {
        _tenantId = tenantId;
        // ...
    }
}

// somewhere else the this is registered     
builder.RegisterType<MessageTenantIdentifier >().As<ITenantIdentifier>().AsSelf();
builder.RegisterGeneratedFactory<MessageTenantIdentifier.Factory>();

问题 工厂只能在消息被处理时使用

public class MsgTypeHandler : IHandleMessages<MsgType>
{
    public MsgTypeHandler(ISettingsService settingsService, MessageTenantIdentifier factory) { ...}
    public async Task Handle(MsgType message)
    {
        var tenantId = message.TenantId;
        // THIS IS THE MOMENT I CAN CONFIGURE THE MessageTenantIdentifier
        var tenantIdentifier = factory.Invoke(tenantId);

        // but this factory is not used against the ISettingsService.  The service to be reused.  <== THE REAL PROBLEM
    }
}

问题

那么,我该如何解决这个问题呢?例如。我应该如何在服务总线中设置 MessageTenantIdentifier 的注册? 还是我的依赖设置完全错误?

【问题讨论】:

    标签: c# dependency-injection autofac rebus


    【解决方案1】:

    如果MsgTypeHandler 类需要ISettingsService,但在租户ID 可用之前无法解析整个对象图,这意味着MsgTypeHandler 就是Composition Root。没关系,但这意味着这是您解析整个对象图的地方,所以不要在这里注入单个服务;相反,注入你需要的工厂:

    public class MsgTypeHandler : IHandleMessages<MsgType>
    {
        public MsgTypeHandler(ISettingsServiceFactory factory) {...}
    
        public async Task Handle(MsgType message)
        {
            var tenantId = message.TenantId;
            ISettingsService svc = this.factory.Create(tenantId);
    
            // User svc here...
        }
    }
    

    【讨论】:

    • 好的,所以我必须编写自己的工厂方法,因为在这种情况下组合根不能依赖于 DI 框架。 (仍然想知道 autofac 是否无法解决这个问题)...
    • @dampee 你可以write the factory in various ways,包括让你的 DI Container 处理细节。
    • 我明白了。我真的需要读一本关于这个主题的书。你的书仍然是一个很好的参考,还是你会建议任何其他的?
    • @dampee 我还是会推荐我的;它被刻意写成尽可能永恒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2016-01-06
    • 2017-04-29
    相关资源
    最近更新 更多