具有 Autofac 依赖项的工厂

2024-01-07

我想编写一个工厂来创建各种类型的“xxNotification”类。我的具体“xxNotification”具有使用 AutoFac 注册的依赖项。我想使用 Autofac 获取/解析“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
        }
    }
}

这看起来是一个很好的候选人策略模式 https://sourcemaking.com/design_patterns/strategy.

接口

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";
    }
}

Strategy

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);
    }
}

Usage

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注册

有几种方法 http://docs.autofac.org/en/latest/faq/select-by-context.html您可以配置 Autofac 来注册同一接口的多个实现,以便在NotificationStrategy构造函数。这里有几个例子:

Scan

// 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")
                    });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有 Autofac 依赖项的工厂 的相关文章

随机推荐

  • 如何在3d中挤出一条路径?

    我正在尝试在 3d 中挤出一条路径 还没有什么奇特的 只是遵循一些点并使用正多边形作为 管道 我现在使用Processing 来快速构建原型 但稍后会将代码转换为OpenGL 我的问题是以直角旋转 关节 我想我大概知道如何获得角度 但不确定
  • opencv中Canny操作自动计算低阈值和高阈值

    在 OpenCV 中 canny 算子的低阈值和高阈值是强制性的 cvCanny input output thresh1 thresh2 在 Matlab 中 有一个选项可以自动计算这些值 edge input canny 我研究了 Ma
  • 匹配两个光栅的分辨率

    我使用两个栅格 每个栅格具有不同的分辨率 我想知道是否有一种更有效的方法将较粗的光栅分辨率与较精细的光栅分辨率相匹配 现在我正在使用蒙版功能来节省一些时间 剪辑到正确的范围并更改分辨率 library raster the raster t
  • LINQ:在 LINQ let 中使用三元 ( ?: ) 是不够的,需要一个“IF”,但似乎无法让它工作

    我试图在 LINQ 的 LET 中包含一个 IF 但我无法让它工作 它似乎适用于三元运算符 但这是 TRUE 或 FALSE 我需要有两个以上的选项 我认为这很好地解释了这一点 基本上我有一个选择 它使用数据库中的联接来选择项目 然后我得到
  • 创建项目后如何让VS2008创建不同的*.DLL名称?

    要在 VS2008 中创建项目 您必须在创建项目时为编译后的输出指定一个名称 如果您正在创建类库 则此输出为 DLL 我可以通过 VS2008 界面更改项目中的所有其他名称 如果我后来后悔输出的名称 我无法找到更改项目的输出 exe 或 d
  • 为什么Class.forName('数据库驱动程序')?

    Why Class forName org apache derby jdbc EmbeddedDriver dbConnection DriverManager getConnection strUrl props 代替 dbConnec
  • 从输入 Haskell 读取数字

    我想要一个函数 它可以读取任意整数 直到插入数字 0 然后显示插入到有序列表中的数字 为此我写了这个函数 import Data List readIntegers IO readIntegers do putStrLn insert a
  • 有没有办法在 TFS 中进行部分签入?

    我有一个包含两个独立修改的文件 我只想犯其中之一 有什么方法可以只签入文件的一部分 无需我修改或搁置 取消搁置它 本质上 在提交时创建一个临时文件 然后将其签入而不是磁盘上的文件 不 唯一的办法就是shelve您有哪些更改 恢复到以前的版本
  • 提高 .NET 中多线程 HttpWebRequest 的性能

    我正在尝试测量网络服务的吞吐量 为了做到这一点 我编写了一个小工具 它可以连续发送请求并从多个线程读取响应 每个线程的内循环内容如下所示 public void PerformRequest WebRequest webRequest We
  • 在 Bootstrap 中重新定位导航栏折叠上的项目

    我正在为网页制作导航栏 我能够制作一个导航栏 其中数据左右对齐 品牌位于中心 但是 当导航栏折叠时 项目的对齐方式变为左 上 品牌 上 右 我希望该品牌保持领先地位 而其他项目则崩溃 这是我的代码
  • 如何在 Ubuntu 10.04 服务器上安装 Jekyll?

    安装 Jekyll 的权威指南似乎是https github com jekyll jekyll https github com jekyll jekyll它说 gem install jekyll 我正在得到一个 ERROR could
  • 我们可以使用其他域的 localStorage 的值吗?

    我正在一个域的本地存储中存储一个值 如果我从同一浏览器访问两个域 我可以从另一个域检索该值吗 不可以 您不能将一个域的本地存储用于另一域 本地存储是基于域的 您无法从不同域上的本地存储读取或写入 即使在其子域上也是如此 您可以通过子域上的
  • 在哪里放置我的 $(document).ready(function(){ 当我在 .js 中有方法时

    我创建了一个 somefile js 其中 somefile js 包含一些 jQuery 方法 例如它包含这个函数 function showWindow divID var dialogDiv divID dialogDiv dialo
  • 如何在python中将base64/radix64公钥转换为pem格式

    有没有任何 python 方法可以将 base64 编码密钥转换为 pem 格式 如何将 ASCII 防护的 PGP 公钥转换为 MIME 编码形式 thanks ASCII armored 和 PEM 非常相似 您只需要更改 BEGIN
  • 检查 Scala 中字符串是否为空或不存在

    我有一个Option String 我想检查是否存在一个字符串 如果存在则不为空 def isBlank input Option String Boolean input isEmpty input filter trim length
  • 如何制作一个广告包装器,在用户运行 adblock 时显示一条消息?

    我有一个网站 每个页面上都有广告 我想显示一条消息 请考虑禁用您的广告拦截 它对我们有很大帮助 如果用户启用了 AdBlock 这是我的尝试 div div 还有我的CSS ad wrapper background color 1D1D1
  • 这是使用 dll 的好方法吗? (C++?)

    我有一个像这样运行的系统 main exe 运行 sub exe 运行 sub2 exe 等等等等 那么 将 sub 和 sub2 更改为 dll 会更快更高效吗 如果可以的话 有人可以指出我在不更改大量代码的情况下制作 dll 的正确方向
  • 在哪里可以手动配置 ActiveMQ 主机名? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我第一次尝试设置 Apache ActiveMQ 我发现我的服务器名称中有一个下划线 这导致 ActiveMQ 无法启动 它抛出这个异常
  • subprocess.check_output 失败并出现错误 127

    我试图从我的 python 应用程序调用外部程序 但它没有显示任何输出 并且失败并出现错误 127 从命令行执行命令工作正常 并且我位于正确的工作目录中 def buildContris self startUrl reportArray
  • 具有 Autofac 依赖项的工厂

    我想编写一个工厂来创建各种类型的 xxNotification 类 我的具体 xxNotification 具有使用 AutoFac 注册的依赖项 我想使用 Autofac 获取 解析 xxNotification 的实例 怎么做 publ