Dependency injection with multiple repositories

后端 未结 4 2095
梦毁少年i
梦毁少年i 2021-02-06 10:13

I have a wcf service and on the client i have:

var service = new ServiceReference1.CACSServiceClient()

The actual service code is:

         


        
4条回答
  •  生来不讨喜
    2021-02-06 10:46

    Preface: This is a general guide to dependency inversion. If you need the default constructor to do the work (e.g. if it is new'ed up by reflection or something else), then it'll be harder to do this cleanly.

    If you want to make your application configurable, it means being able to vary how your object graph is constructed. In really simple terms, if you want to vary an implementation of something (e.g. sometimes you want an instance of UserRepository, other times you want an instance of MemoryUserRepository), then the type that uses the implementation (CACService in this case) should not be charged with newing it up. Each use of new binds you to a specific implementation. Misko has written some nice articles about this point.

    The dependency inversion principle is often called "parametrise from above", as each concrete type receives its (already instantiated) dependencies from the caller.

    To put this into practice, move the object creation code out of the CACService's parameterless constructor and put it in a factory, instead.

    You can then choose to wire up things differently based on things like:

    • reading in a configuration file
    • passing in arguments to the factory
    • creating a different type of factory

    Separating types into two categories (types that create things and types that do things) is a powerful technique.

    E.g. here's one relatively simple way of doing it using a factory interface -- we simply new up whichever factory is appropriate for our needs and call its Create method. We use a Dependency Injection container (Autofac) to do this stuff at work, but it may be overkill for your needs.

    public interface ICACServiceFactory
    {
        CACService Create();
    }
    
    // A factory responsible for creating a 'real' version
    public class RemoteCACServiceFactory : ICACServiceFactory
    {
        public CACService Create()
        {
             return new CACService(new UserRepository(), new BusinessRepository());
        }        
    }
    
    // Returns a service configuration for local runs & unit testing
    public class LocalCACServiceFactory : ICACServiceFactory
    {
        public CACService Create()
        {
             return new CACService(
                   new MemoryUserRepository(), 
                   new MemoryBusinessRepository());
        }     
    }
    

提交回复
热议问题