【问题标题】:Ninject factory that fulfills Open/Closed principle?满足开放/封闭原则的Ninject工厂?
【发布时间】:2015-12-22 13:15:59
【问题描述】:

我正在寻找创建符合 Open/Closed 标准的工厂的解决方案。 我们可以通过反射非常简单地实现它(实例化所有实现特定接口的类,这些类存在于ex.当前程序集中,将它们存储在一些字典中,键基于静态属性,并根据传递给 CreateInstance 方法的参数返回特定实例)。

我想知道这是否可以使用 Ninject。 我买了“Mastering Ninject for Dependency Injection”一书,其中有一章“满足现实世界的要求”和 Telcom Switch 示例。 不幸的是,IStatusCollectorFactory 和所有实现这个接口的工厂都违反了打开/关闭原则——如果你想添加对新类的支持,你必须改变接口。

有什么帮助吗?:)

/// Interface for classes that define factory able to create currency defaltion instances. 
public interface ICurrencyDeflationFactory
{
    ICurrencyDeflation CreateInstance(string currencyCode);
}


/// <summary>
/// Interface for classes that define deflation table in specific currency.
/// </summary>
public interface ICurrencyDeflation
{
    /// <summary>
    /// Current currency code as defined in ISO 4217
    /// </summary>
    string CurrencyCode { get; }

    /// <summary>
    /// Deflation table used during conversion.
    /// </summary>
    string[,] GetDeflationTable { get; }
}

【问题讨论】:

  • 这种工厂的预期接口是什么?它应该如何知道要返回哪个对象?你能提供一些细节吗?另外,你能解释一下为什么需要它吗?具体来说,它的客户是谁?
  • 我编辑了我的帖子以包含信息。
  • 虽然与 NInject 无关,但您可能会发现 this article 很有帮助
  • 这可以使用自定义实例提供程序来完成,看看docs

标签: c# ninject


【解决方案1】:

感谢您的反馈。我设法实现了我想要的(在我看来:))这是一个潜在的解决方案: 内核注册:

kernel.Bind<ICurrencyDeflationFactory>().To<CurrencyDeflationFactory>(); 
kernel.Bind(x => x.FromAssemblyContaining<ICurrencyDeflation>()
  .SelectAllClasses()
  .InheritedFrom<ICurrencyDeflation>()
  .BindAllInterfaces());

工厂界面:

/// <summary>
/// Interface for classes that define factory able to create currency defaltion instances.
/// </summary>
public interface ICurrencyDeflationFactory
{
    List<ICurrencyDeflation> CurrencyList { get; }
    ICurrencyDeflation CreateInstance(string currencyCode);
}

放气界面:

    /// <summary>
/// Interface for classes that define deflation table in specific currency.
/// </summary>
public interface ICurrencyDeflation
{
    /// <summary>
    /// Current currency code as stands in ISO 4217
    /// </summary>
    string CurrencyCode { get; }

    /// <summary>
    /// Deflation table used during conversion.
    /// </summary>
    string[,] GetDeflationTable { get; }
}

工厂混凝土:

public class CurrencyDeflationFactory : ICurrencyDeflationFactory
{ 
    List<ICurrencyDeflation> deflationCollection;
    public CurrencyDeflationFactory(List<ICurrencyDeflation> definedDeflations)
    {
        this.deflationCollection = definedDeflations;
    }
    public List<ICurrencyDeflation> CurrencyList
    {
        get
        {
            return deflationCollection;
        }
    }

    public ICurrencyDeflation CreateInstance(string currencyCode)
    {
        return deflationCollection.Find(x => x.CurrencyCode.Equals(currencyCode));
    }
}

为了获得美元通货紧缩:

 var currencyDeflation = kernel.Get<ICurrencyDeflationFactory>().CreateInstance("USD");

因此,我不必:
1) 更改主程序以将新类注册到内核
2) 新的通货紧缩只是一个实现 IDeflationCurrency 的新类
3) 每个实现 IDeflationCurrency 的类都将在运行时可用,无需更改现有代码(关闭修改)
4) 如果需要,我可以在不触及现有代码的情况下添加新的通货紧缩(开放扩展)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2018-06-11
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    相关资源
    最近更新 更多