我想写一个工厂来创建各种类型的" xxNotification"类。我的具体" xxNotification"具有在AutoFac中注册的依赖项。我想得到/解决" xxNotification"的实例使用Autofac。怎么做?
public interface INotification
{
void Notify(string Action, int OrderID);
}
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 class NotificationFactory
{
public INotification GetNotification(string NotificationName)
{
switch (NotificationName)
{
case "MagentoOrderStateNotification":
//resolve instance of MagentoOrderStateNotification
}
}
}
答案 0 :(得分:1)
这似乎是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);
}
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问题。
有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")
});