DI / IOC NHibernate和在让他们一起工作的帮助 [英] DI/IoC, NHibernate and help in getting them to work together

查看:138
本文介绍了DI / IOC NHibernate和在让他们一起工作的帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我周围的DI / IOC NHibernate的头,让他们很好地协同工作为我开发的应用程序。我是很新的这两个NHibernate和DI /国际奥委会所以不太清楚我在做什么是否是明智的方法是想一下吧。这是该方案

I'm trying to get my head around DI/IoC, NHibernate and getting them to work nicely together for an application that i'm developing. I'm quite new to both NHibernate and DI/IoC so not quite sure whether what i'm doing is the sensible way to be going about it. This is the scenario:

该应用为用户提供了用于计算一个特定金融交易的特定值(称为边缘)的能力。每个事务的marging值的计算是由要使用的抽象MarginCalculator类和具体实施的具体实施方式进行了取决于产品的用于特定交易(由产品对象的一个​​特定字段中给出)的类型。具体计算器类是通过对产品类的属性进行访问。 。即

The application provides users with the ability to calculate a particular value (known as the margin) for a particular financial transaction. The calculation of the marging value for each transaction is carried out by concrete implementations of an abstract MarginCalculator class and the concrete implementation to be used depends on the type of the product for the particular transaction (given by a certain field of the product object). The concrete calculator class is accessed via a property on the product class. i.e.

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容器)即

Users select a particular client and Product from dropdowns and the corresponding clientId and productId are passed to repositories that then use NHibernate to populate product and client objects before they're injected into the transaction object. In my current setup the Transaction receives its Product and Client dependencies via constructor dependency injection (no IoC container used as yet) i.e.

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

/* Similar repository for Clients */

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

Transaction t = new Transaction(p, c);



下面是什么,我希望得到的想法:

The following are what i'm hoping to get ideas on:

一个。 *是否考虑行通过产品领域对象访问MarginCalculator(其本质上是一种服务)或应作为建议在这里,(< A HREF =htt​​p://www.lostechies.com/blogs/jimmy_bogard/archive/2008/03/31/ptom-the-dependency-inversion-principle.aspx相对=nofollow> HTTP://计算器。 COM /问题/ 340461 /依赖注入与 - NHibernate的对象代码进行重组,以便从域对象删除服务的依存关系,而是创建一个新的TransactionProcessor类,它抽象MarginCalculator作为依赖)(沿着什么这里描述(的 http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/03/31/ptom-the-dependency-inversion-principle.aspx ),即*

A. *Is it considered OK to be accessing the MarginCalculator (which is essentially a service) through the Product domain object or should, as suggested here, (http://stackoverflow.com/questions/340461/dependency-injection-with-nhibernate-objects) the code be restructured so as to remove service dependencies from the domain objects and instead create a new TransactionProcessor class that takes the abstract MarginCalculator as a dependency (along the lines of what's described here (http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/03/31/ptom-the-dependency-inversion-principle.aspx) i.e.*

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



乙。 是它可以使用IoC容器来获得与NHibernate填充/产生的产品和客户的依赖事务对象注入?也就是说给定产品标识和客户端ID,用户双方提供的,是有可能有一些这样的:

B. Is it possible to use an IoC Container to get a Transaction object with NHibernate populated/generated Product and Client dependencies injected? i.e. Given a productId and clientId, both provided by the user, is it possible to have something like:

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



使得容器可解决该交易对象的产品和客户端相关性,NHibernate的被用于填充产品和客户端基于产品ID和的clientId然后填充产品和客户端被注入交易?

such that the container resolves the Product and Client dependencies of the Transaction object, NHibernate is utilised to populate the Product and Client based on the productId and clientId and then the populated Product and Client are injected into the Transaction?

<强>℃。在一个典型的DI情况下,如果A类对接口b的依赖那么下面可以这样做:

C. In a typical DI scenario, if class A has a dependency on interface B then the following might be done:

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办法

However, this, which is virtually how all examples of DI are shown, assumes that the implementor of IInterfaceB (in this case Class B) is known at design time. Is there a way to use DI in such a way that the implementor is determined at runtime?

非常感谢

推荐答案

下面是我对你的问题的第二卷带:

Here's my second take on your questions:

答:在最佳实践方面,你可以离开服务依存关系到域中的对象,只要你确保你根据接口类型。大部分(如果不是全部)的容器可以做到这类型的注入对你,这是很琐碎,模拟出的每个服务的依赖,所以你可以测试你的具体类所有的行为。我只建议使用抽象类,如果你想重构出样板实现特定接口的实现,比如用一个基类做你的通用CRUD持久性的工作。

A: In terms of best practice, you can leave the service dependency into the domain object as long as you make sure that you're depending on an interface type. Most (if not all) containers can do that type of injection for you, and it's pretty trivial to mock out each service dependency so you can test every behavior in your concrete classes. I only recommend using abstract classes if you want to refactor out the boilerplate implementation for a particular interface implementation, such as using a base class to do your generic CRUD persistence work.

b和C:

这是很好的知道,这种功能是可用的。我想,一个更重要的问题是什么,我试图做的是,其实常见的做法,不管它是好的做法。即

It's good to know that this kind of functionality is available. I suppose a more important question is whether what i'm trying to do is in fact common practice and whether it's considered good practice. i.e.


  1. 有一个容器决心和使用的持久化框架(如NHibernate的),并注入已预先填充依赖>

  2. 有容器注入的具体实现,其中的具体落实在运行时确定抽象的依赖。

此外,在IOC / DI / NHibernate的术语,做什么我谈论,有一个特别的名字吗?是它,例如,的特征之一在该比较或.net的IoC框架此比较列出?我想了解其他的IoC框架(如温莎城堡)是否包含这些功能一样不李林甫,但我不知道是否有什么我描述了一个特别的名字,所以我不知道该怎么寻找:)

Also, in IoC/DI/NHibernate terminology, does what i'm talking about, have a particular name? Is it, for example, one of the features listed in this comparison or this comparison of .net IoC frameworks? I'd like to read about whether other IoC frameworks (like Castle Windsor) include these functionalities like LinFu does but i don't know whether what i'm describing has a particular name so i don't know what to search for :)

我相信你实际上是指在发布的此链接

I believe you're actually referring to the comparison posted at this link.

1)AFAIK,这是标准的做法,做服务注射,但注射您提到的类型将是困难的,因为一些其他框架做你必须使用的域对象ID来解决这些依赖关系在运行时,也不是所有的容器都支持该类型的动态清晰度(又名语境结合)的。所有的事情都是平等的(并假设它可以与其他容器来完成),这似乎与DI应用的唯一最佳实践/ IoC的是,你必须使用的接口为您服务的依赖。

1) AFAIK, it's standard practice to do service injection, but the type of injection that you're referring to would be difficult to do for some of the other frameworks since you have to use domain object IDs to resolve these dependencies at run time, and not all containers support that type of dynamic resolution (aka 'contextual binding'). All things being equal (and assuming that this can be done with the other containers), the only 'best practice' that seems to apply with DI/IoC is that you must use interfaces for your service dependencies.

如何将这些依赖关系最终应构建并解决应完全取决于你,并在你的情况,它确实没有,如果你得到这些依赖从填充物质持久性框架,只要容器本身能消除大部分的样板分辨率代码为您服务。

How these dependencies should be ultimately constructed and resolved should be completely up to you, and in your case, it really doesn't matter if you get these dependencies populated from a persistence framework as long as the container itself is able to eliminate most of the boilerplate resolution code for you.

2)具体的服务注入DI / IOC框架中的标准,大多可以解决在运行时的依赖;然而,这些框架的方式和位置的注入可以做不同的。

2) Concrete service injection is standard among DI/IOC frameworks, and most of them can resolve dependencies at runtime; however, these frameworks differ on how and where that injection can be done.

仅供参考,你应该注意这两个功能都构造器注入属性注入。基于您的代码示例中,我会说,你会更倾向于使用构造器注入,所以你可能要留意每个相应的框架如何做这种类型的注入为您服务。 HTH:)

FYI, the two features that you should pay attention to are Constructor Injection and Property Injection. Based on your code examples, I'd say that you'd be more inclined to use constructor injection, so you might want to keep an eye out for how each respective framework does that type of injection for you. HTH :)

这篇关于DI / IOC NHibernate和在让他们一起工作的帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆