当前位置:  开发笔记 > 编程语言 > 正文

DI/IoC,NHibernate并帮助他们一起工作

如何解决《DI/IoC,NHibernate并帮助他们一起工作》经验,为你挑选了0个好方法。

我正试图了解DI/IoC,NHibernate并让它们在我正在开发的应用程序中很好地协同工作.我对NHibernate和DI/IoC都很陌生,所以不太确定我所做的是否是合理的方式.这是场景:

该应用程序为用户提供了计算特定金融交易的特定值(称为保证金)的能力.每个事务的marging值的计算是通过抽象MarginCalculator类的具体实现来执行的,并且要使用的具体实现取决于特定事务的产品类型(由产品对象的某个字段给出).具体的计算器类可通过产品类的属性访问.即

public class Transaction
{
    private double _margin;
    private Product _product;
    private Client _client;

    public double Margin { get; }
    public Product Product { get; }
    public Client Client { get; }

    public Transaction(Product p, Client c)
    {
        _product = p;
        _client = c;
    }

    public void CalculateMargin()
    {
        _margin = _product.MarginCalculator.CalculateMargin();
    }
}

public class Product
{
    private string _id;
    private string _productType;
    ... Other fields

    public string Id { get; }
    public string ProductType { get; }
    public MarginCalculator MarginCalculator
    {
        get { return MarginCalculatorAssembler.Instance.CreateMarginCalculatorFor(this.ProductType); }
    }
}

public class MarginCalculatorAssembler
{
    public static readonly MarginCalculatorAssembler Instance = new MarginCalculatorAssembler();

    private MarginCalculatorAssembler ()
    {
    }

    public MarginCalculator CreateMarginCalculatorFor(string productType)
    {
        switch (productType)
        {
            case "A":
                return new ConcreteMarginCalculatorA();
            case "B":
                return new ConcreteMarginCalculatorB();
            default:
                throw new ArgumentException();
        }
    }
}

public abstract class MarginCalculator
{
    public abstract double CalculateMargin();
}

public class ConcreteMarginCalculatorA : MarginCalculator
{
    public override double CalculateMargin
    {
        // Perform actual calculation
    }
}

public class ConcreteMarginCalculatorB : MarginCalculator
{
    public override double CalculateMargin
    {
        // Perform actual calculation
    }
}

用户从下拉列表中选择特定客户端和产品,并将相应的clientId和productId传递给存储库,然后使用NHibernate在将产品和客户端对象注入事务对象之前填充它们.在我当前的设置中,事务通过构造函数依赖注入(尚未使用IoC容器)接收其产品和客户端依赖关系

public class ProductRepository : IRepository
{
    public Product GetById(string id)
    {
        using (ISession session = NHibernateHelper.OpenSession())
            return session.Get(id);
    }
}

/* Similar repository for Clients */

IRepository clientRepository = new ClientRepository();
IRepository productRepository = new ProductRepository();
Client c = clientRepository.GetById(clientId);
Product p = productRepository.GetById(productId);

Transaction t = new Transaction(p, c);

以下是我希望得到的想法:

A. 通过Product域对象访问MarginCalculator(实际上是一项服务)是否可以,或者应该按照此处的建议(http://stackoverflow.com/questions/340461/dependency-injection-with-nhibernate) -objects)重构代码以便从域对象中删除服务依赖性,而是创建一个新的TransactionProcessor类,它将抽象的MarginCalculator作为依赖项(沿着这里所描述的行(http://www.lostechies.com) /blogs/jimmy_bogard/archive/2008/03/31/ptom-the-dependency-inversion-principle.aspx)即

public class TransactionProcessor
{
    private readonly MarginCalculator _marginCalculator;

    public TransactionProcessor(MarginCalculator marginCalculator)
    {
        _marginCalculator = marginCalculator;
    }

    public double CalculateMargin(Transaction t)
    {
        return _marginCalculator.CalculateMargin(Transaction t);
    }
}

public abstract class MarginCalculator
{
    public abstract double CalculateMargin(Transaction t);
}

B. 是否可以使用IoC容器来获取具有注入的NHibernate填充/生成的产品和客户端依赖关系的Transaction对象?即,给定由用户提供的productId和clientId,是否可能具有如下内容:

// pseudocode
Transaction t = IoC.Resolve(productId, clientId);

如果容器解析了Transaction对象的Product和Client依赖关系,NHibernate用于根据productId和clientId填充Product和Client,然后将填充的Product和Client注入到Transaction中?

C.在典型的DI场景中,如果A类依赖于接口B,则可能会执行以下操作:

IInterfaceB b = new ClassB();
A a = new A(b);

interface IInterfaceB
{
}

class B : IInterfaceB
{
}

public class A
{
    private IIntefaceB _b;

    public A(IInterfaceB b)
    {
        _b = b;
    }
}

然而,这实际上是如何显示DI的所有示例,假设IInterfaceB的实现者(在这种情况下为B类)在设计时是已知的.有没有办法以这样的方式使用DI,以便在运行时确定实现者?

非常感谢

马修

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有