简体   繁体   中英

WCF Service Testability and Dependency Injection

I've a WCF Service which is hosted inside MVC Application . 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. I want to know how should I implement a nice and clean DI for WCF Service.

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. What you would do is have a field (usually private ) of type IRepositoryA on it. 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 :

For more information on the Dependency Inversion Principle, just read what Uncle Bob has to say .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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