这看起来是一个很好的候选人
Strategy Pattern
接口
public interface INotification
{
void Notify(string Action, int OrderID);
bool AppliesTo(string NotificationName);
}
public interface INotificationStrategy
{
void Notify(string NotificationName, string Action, int OrderID);
}
INotification实现
public class MagentoOrderStateNotification : INotification
{
private readonly GenericRepository<Order> _orderRepository;
private readonly OMRestIntegrationService _oMRestIntegrationService;
public MagentoOrderStateNotification(GenericRepository<Order> orderRepository, OMRestIntegrationService oMRestIntegrationService)
{
_orderRepository = orderRepository;
_oMRestIntegrationService = oMRestIntegrationService;
}
public void Notify(string Action, int OrderID)
{
//implementation...
}
public bool AppliesTo(string NotificationName)
{
// Note that you can make the criteria to use this
// service as advanced as you need to. You could even
// design your strategy to use multiple services in specific
// scenarios. But putting that logic here has many advantages
// over a switch case statement.
return NotificationName == "a";
}
}
public class FooOrderStateNotification : INotification
{
public void Notify(string Action, int OrderID)
{
//implementation...
}
public bool AppliesTo(string NotificationName)
{
return NotificationName == "b";
}
}
策略
public class NotificationStrategy : INotificationStrategy
{
private readonly IEnumerable<INotification> oNotifications;
public MessageStrategy(IEnumerable<INotification> oNotifications)
{
if (oNotifications == null)
throw new ArgumentNullException("oNotifications");
this.oNotifications = oNotifications;
}
public void Notify(string NotificationName, string Action, int OrderID)
{
var notification = this.oNotifications
.FirstOrDefault(x => x.AppliesTo(NotificationName));
// Possible alternative: get multiple implementations and
// then loop through them, executing each one.
// var notifications = this.oNotifications
// .Where(x => x.AppliesTo(NotificationName)).ToArray();
if (notification == null)
{
throw new Exception("No notification type registered for " + NotificationName);
}
notification.Notify(Action, OrderID);
}
}
public class SomeService : ISomeService
{
private readonly INotificationStrategy oNotificationStrategy;
public SomeService(INotificationStrategy oNotificationStrategy)
{
if (oNotificationStrategy == null)
throw new ArgumentNullException("oNotificationStrategy");
this.oNotificationStrategy = oNotificationStrategy;
}
public void DoSomething()
{
this.oNotificationStrategy.Notify("a", "Hello", 1234);
}
}
注意,另一种方法是使用基于OrderID的一些“OrderType”状态来查找要使用的服务(不确定将OrderID传递到Notify()方法中是否有意义)。但不管你如何划分,这是一个应用程序设计问题,而不是DI问题。
Autofac注册
有
a few ways
您可以将Autofac配置为注册同一接口的多个实现,以便在中使用
NotificationStrategy
扫描
// Note you may need more than one registration if you are spanning
// multiple assemblies.
builder.RegisterAssemblyTypes(typeof(INotification).Assembly)
.Where(x => typeof(INotification).IsAssignableFrom(x))
.AsImplementedInterfaces();
当以这种方式注册实现时,Autofac将隐式地将所有实现注入任何
IEnumerable<INotification>
樱桃采摘
builder.Register<MagentoOrderStateNotification>()
.Named<INotification>("magentoOrderStateNotification");
builder.Register<FooOrderStateNotification>()
.Named<INotification>("fooOrderStateNotification");
builder.RegisterType<NotificationStrategy>()
.As<INotificationStrategy>()
.WithParameter(
(p, c) => p.Name == "oNotifications",
(p, c) => new[]
{
c.ResolveNamed<INotification>("magentoOrderStateNotification"),
c.ResolveNamed<INotification>("fooOrderStateNotification")
});