使用工厂解决依赖
Use factory to resolve dependencies
我们有一个带有 autofac 的网络解决方案。现在我们想在 windows service/console 应用程序中重用内容,其中内容仅在消息来自企业总线时才可用。
我有以下服务可以重用
public SettingsService : ISettingsService {
public readonly ITenantIdentifer _tenantIdentifier
public SettingsService (ITenantIdentifier tenantIdentifier) {
this._tenantIdentifier =tenantIdentifier;
}
// do other stuff
}
当前工作设置
Web 上下文的 ITenantIdentifier
仅使用 builder.RegisterType<WebTenantIdentifier>().As<ITenantIdentifier>();
.
为 Web 应用程序注册
一切正常。
我们的企业总线
在消息可用之前,企业总线无法解析 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 的注册?
还是我的依赖设置完全错误?
如果 MsgTypeHandler
class 需要一个 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...
}
}
我们有一个带有 autofac 的网络解决方案。现在我们想在 windows service/console 应用程序中重用内容,其中内容仅在消息来自企业总线时才可用。
我有以下服务可以重用
public SettingsService : ISettingsService {
public readonly ITenantIdentifer _tenantIdentifier
public SettingsService (ITenantIdentifier tenantIdentifier) {
this._tenantIdentifier =tenantIdentifier;
}
// do other stuff
}
当前工作设置
Web 上下文的 ITenantIdentifier
仅使用 builder.RegisterType<WebTenantIdentifier>().As<ITenantIdentifier>();
.
为 Web 应用程序注册
一切正常。
我们的企业总线
在消息可用之前,企业总线无法解析 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 的注册? 还是我的依赖设置完全错误?
如果 MsgTypeHandler
class 需要一个 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...
}
}