【发布时间】:2019-05-28 10:45:35
【问题描述】:
大家好,
我有一个问题,我有一个这样的界面:
public interface ICommand<in TRequest, out TResponse>
where TRequest : class
where TResponse : BaseResponse
{
TResponse Execute(TRequest request);
}
然后我两个类实现这个接口是这样的:
public class ExternalAddUser : ICommand<ExternalAddUserRequest, ExternalAddUserResponse>
{
private readonly ICommand<AddUserRequest, AddUserResponse> _command;
public ExternalAddUser(ICommand<AddUserRequest, AddUserResponse> command)
{
_command = command;
}
public ExternalAddUserResponse Execute(ExternalAddUserRequest request)
{
var response = _command.Execute(Mapper.Map<AddUserRequest>(request));
return Mapper.Map<ExternalAddUserResponse>(response);
}
}
还有这个:
public class AddUser : ICommand<AddUserRequest, AddUserResponse>
{
private readonly IUnitOfWork _unitOfWork;
private readonly IMessageService _messageService;
private readonly IDefaultSettings _settings;
private readonly IMessageFactory _messageFactory;
public AddUser(IUnitOfWork unitOfWork, IMessageService messageService, IDefaultSettings settings, IMessageFactory messageFactory)
{
_unitOfWork = unitOfWork;
_messageService = messageService;
_settings = settings;
_messageFactory = messageFactory;
}
public AddUserResponse Execute(AddUserRequest request)
{
// My implementation here
}
}
Interface IMessageFactory 是一个“工厂/模板”模式,它创建一个只有以下属性的 IMessage 接口:Body、Subject、Language。 我已经用这样的简单注射器注册了我的课程:
container.Register(typeof(ICommand<,>), businessLayerAssembly);
container.Register<IDefaultSettings, DefaultSettings>(Lifestyle.Singleton);
container.Register<ISecuritySettings, SecuritySettings>(Lifestyle.Singleton);
container.RegisterConditional<IMessageFactory, ActivationMessageFactory>
(c => c.Consumer.ImplementationType == typeof(AddUser)
|| c.Consumer.ImplementationType == typeof(SendActivationEmail));
container.RegisterConditional<IMessageFactory, RecoveryMessageFactory>
(c => !c.Handled);
现在我有另一个类是 ActivationMessageFactory 的装饰器,如下所示:
public class ActivationMessageWithoutLinkFactory : IMessageFactory
{
private readonly IMessageFactory _messageFactory;
public ActivationMessageWithoutLinkFactory(IMessageFactory messageFactory)
{
_messageFactory = messageFactory;
}
public IMessage CreateMessage(MessageData messageData)
{
// Implementation
}
}
我的问题是:
当从 ExternalAddUser 类调用此类时,是否可以在 AddUser 类中注入 ActivationMessageWithoutLinkFactory 装饰器?
气味代码示例:
public class ExternalAddUser : ICommand<ExternalAddUserRequest, ExternalAddUserResponse>
{
public ExternalAddUserResponse Execute(ExternalAddUserRequest request)
{
ICommand<AddUserRequest, AddUserResponse> command = new AddUser(new SqlUnitOfWork(), new EmailService(),
new DefaultSettings(), new ActivationMessageWithoutLinkFactory(new ActivationMessageFactory()));
}
}
这是我要构建的对象图:
// AddUser injected into ExternalAddUser
new ExternalAddUser(
new AddUser(
new UnitOfWork(),
new MessageService(),
new DefaultSettings(),
new ActivationMessageWithoutLinkFactory(
new ActivationMessageFactory())))
// AddUser injected into anything else
new AnythingElse(
new AddUser(
new UnitOfWork(),
new MessageService(),
new DefaultSettings(),
new ActivationMessageFactory())) // no decorator
谢谢你的回答,希望我清楚。
【问题讨论】:
-
我们可以尝试基于消费者的基于条件的注入吗? simpleinjector.readthedocs.io/en/latest/…
-
类似
container.RegisterConditional<IMessageFactory , ActivationMessageWithoutLinkFactory >( c => c.Consumer.ImplementationType == typeof(ExternalAddUser)); -
不,我已经尝试过了,但是这个解决方案不起作用。
-
所以你嵌套了
ICommand接口?这似乎是你问题的来源。看看this -
我的问题是如何注册这个:
ICommand <AddUserRequest, AddUserResponse> command = new AddUser (new SqlUnitOfWork (), new EmailService (), new DefaultSettings (), new ActivationMessageWithoutLinkFactory (new ActivationMessageFactory ());即,如何在AddUser类中注入装饰器ActivationMessageWithoutLinkFactory只有当它被特定类ExternalAddUser调用时。我希望我更清楚了。谢谢@Ric.Net
标签: c# .net design-patterns dependency-injection simple-injector