简体   繁体   English

WCF服务可测试性和依赖注入

[英]WCF Service Testability and Dependency Injection

I've a WCF Service which is hosted inside MVC Application . 我有一个WCF服务 ,该服务托管在MVC应用程序内部。 Service interacts with several Repository (I've Code First design) to do its job. 服务与多个存储库(我已通过代码优先设计)进行交互以完成其工作。 Currently I create an instance of all Repository classes inside each Service method, I think it is bad and my Service is totally coupled to Repository classes. 当前,我在每个Service方法内创建所有Repository类的实例,我认为这很不好,并且我的Service已完全耦合到Repository类。 I want to know how should I implement a nice and clean DI for WCF Service. 我想知道如何为WCF服务实现良好而干净的DI。

Thanks in Advance. 提前致谢。

I would recommend using the Dependency Inversion Principle: Have your repositories implement a specific interface, then have your service classes take in an object (or objects) of that interface (or interfaces). 我建议使用依赖性反转原则:让您的存储库实现特定的接口,然后让服务类接受该接口(或多个接口)的一个或多个对象。 Do not have it directly reference the concrete class. 不要直接引用具体的类。 Then, all you'd need to do on your service class is call a method that's exposed by the interface to bring up any/all of the information that you want. 然后,您需要对服务类进行的所有操作就是调用接口公开的方法,以调出所需的任何/所有信息。

Doing so will de-couple the code from each other, since they'd both be relying on abstractions, and you'll still get the wonderful functionality that you're requesting. 这样做将使代码彼此分离,因为它们都依赖于抽象,并且您仍将获得所需的出色功能。

Here's how you could go about doing it: Let's say your WCF service class needs RepositoryA, which implements IRepositoryA. 这是您可以执行的操作:假设您的WCF服务类需要RepositoryA,该实现IRepositoryA。 What you would do is have a field (usually private ) of type IRepositoryA on it. 您将要做的是在其上具有IRepositoryA类型的字段(通常为private )。 Then create a constructor in the service that takes in an object of type IRepositoryA, and then sets the field variable with that object being passed in. Something like what's found on this site : 然后在服务中创建一个构造函数,该构造函数接受IRepositoryA类型的对象,然后设置传递该对​​象的字段变量。类似于在此站点上找到的内容:

For more information on the Dependency Inversion Principle, just read what Uncle Bob has to say . 有关依赖倒置原则的更多信息,请阅读Bob叔叔要说的内容

One approach you can take is to inject a repository factory in your service class and then call/get your repository from the factory. 您可以采用的一种方法是在服务类中注入存储库工厂,然后从工厂调用/获取存储库。

Repository Factory: 仓库工厂:

public interface IRepositoryFactory
{
    IRepositoryOne GetRepositoryOne();
    IRepositoryTwo GetRepositoryTwo();
}

public class RepositoryFactory: IRepositoryFactory
{
    public DataAccess.RepositoryInterfaces.IRepositoryOne GetRepositoryOne()
    {
        return new RepositoryOne();
    }
    public DataAccess.RepositoryInterfaces.IRepositoryTwo GetRepositoryTwo()
    {
        return new RepositoryTwo();
    }
}

Service Class: 服务等级:

public ServiceClass: IService
{

    private readonly IRepositoryFactory _repositoryFactory;

    public ServiceClass(IRepositoryFactory factory)
    {
        _repositoryFactory = factory;
    }

    public IList<YourItems> GetYourItems()
    {
        var repository = _repositoryFactory.GetRepositoryOne();
        return repository.GetItems(....);
    }
}

With this approach, you'll need to register and resolve only your repository factory, not all the individual repositories. 使用这种方法,您只需要注册和解析您的存储库工厂,而无需注册和解析所有单个存储库。 This is sort of hybrid approach, but I think it's very clean and easy to understand. 这是一种混合方法,但我认为它非常干净且易于理解。 Of course, you can always not use a factory and resolve your repositories in every call. 当然,您始终不能在每次调用中都使用工厂来解析存储库。 I can show a sample of that too, if you'd like. 如果您愿意,我也可以显示一个示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM