具有 Autofac 依赖项的工厂
Factory with Autofac dependencies
我想写一个工厂来创建各种类型的 "xxNotification" 类。我的混凝土 "xxNotification" 具有在 AutoFac 中注册的依赖项。我想使用 Autofac get/resolve "xxNotification" 的实例。怎么做?
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
}
}
}
这看起来很适合 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")
});
我想写一个工厂来创建各种类型的 "xxNotification" 类。我的混凝土 "xxNotification" 具有在 AutoFac 中注册的依赖项。我想使用 Autofac get/resolve "xxNotification" 的实例。怎么做?
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
}
}
}
这看起来很适合 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")
});