Ответ 1
Вы можете использовать именованные экземпляры или интеллектуальные экземпляры, чтобы решить эту проблему...
// Named instances
this.For<IMessageService>().Use<EmailService>().Named("emailService");
this.For<IMessageService>().Use<SmsService>().Named("smsService");
// Smart instances
var emailService = this.For<IMessageService>().Use<EmailService>();
var smsService = For<IMessageService>().Use<SmsService>();
this.For<ISomeService>().Use<SomeService>()
.Ctor<IMessageService>("emailService").Is(emailService)
.Ctor<IMessageService>("smsService").Is(smsService);
Но я бы сказал, что ваш дизайн нуждается в некоторой работе. Тот факт, что ваша служба знает разницу между службой электронной почты и услугой SMS, является нарушением Принципа замещения Лискова. Лучший подход, чем введение двух параметров одного и того же типа, заключается в использовании составного шаблона .
public class CompositeMessageService : IMessageService
{
private readonly IMessageService messageServices;
public CompositeMessageService(IMessageService[] messageServices)
{
if (messageServices == null)
throw new ArgumentNullException("messageServices");
this.messageServices = messageServices;
}
public void Send(IMessage message)
{
foreach (var messageService in this.messageServices)
{
messageService.Send(message);
}
}
}
В исходной службе необходимо принять только один экземпляр IMessageService
. Ему не нужно знать подробные сведения о том, к какому типу IMessageService
он имеет дело.
public SomeService(IMessageService messageService)
В StructureMap вы можете легко зарегистрировать все экземпляры IMessageService и автоматически введет их в массив аргументов конструктора IMessageService.
this.Scan(scan =>
{
scan.TheCallingAssembly();
scan.AssemblyContainingType<IMessageService>();
scan.AddAllTypesOf<IMessageService>();
});
Или вы можете явно вводить экземпляры.
this.For<IMessageService>().Use<CompositeMessageService>()
.EnumerableOf<IMessageService>().Contains(x =>
{
x.Type<EmailService>();
x.Type<SmsService>();
});
Это означает, что ваша конфигурация может быть изменена, чтобы изменить порядок обслуживания. С вашим текущим дизайном эти детали жестко закодированы в службе, которая принимает 2 параметра.
Кроме того, вы получаете возможность добавлять дополнительные службы сообщений или удалять существующие службы сообщений без изменения дизайна.