How to Resolve type based on end-user configuration value?

前端 未结 1 862
太阳男子
太阳男子 2020-12-10 14:29

I have an interface (call it IAcmeService) that has multiple implementations.

FileSystemAcmeService
DatabaseAcmeService
NetworkAcmeService

相关标签:
1条回答
  • 2020-12-10 14:59

    Defining and implementing and Abstract Factory is the standard solution to this type of problem. If you will pardon my use of C#, you can define an IAcmeServiceFactory interface like this:

    public interface IAcmeServiceFactory
    {
        IAcmeService Create(string serviceName);
    }
    

    You can now write a concrete implementation like this one:

    public class AcmeServiceFactory : IAcmeServiceFactory
    {
        private readonly IAcmeService fsService;
        private readonly IAcmeService dbService;
        private readonly IAcmeService nwService;
    
        public AcmeServiceFactory(IAcmeService fsService,
            IAcmeService dbService, IAcmeService nwService)
        {
            if (fsService == null)
            {
                throw new ArgumentNullException("fsService");
            }
            if (dbService == null)
            {
                throw new ArgumentNullException("dbService");
            }
            if (nwService == null)
            {
                throw new ArgumentNullException("nwService");
            }
    
            this.fsService = fsService;
            this.dbService = dbService;
            this.nwService = nwService;
        }
    
        public IAcmeService Create(string serviceName)
        {
            switch case serviceName
            {
                case "fs":
                    return this.fsService;
                case "db":
                    return this.dbService;
                case "nw":
                    return this.nwService;
                case default:
                    throw new ArgumentException("serviceName");
            }
        } 
    }
    

    You can make it more general-purpose if you want to be able to create an arbitrary number of IAcmeService instances, but I will leave that as an exercise to the reader :)

    This will require you to register the Factory with Unity as well. In any place where you need an IAcmeService based on a name, you take a dependency on IAcmeServiceFactory instead of IAcmeService itself.

    0 讨论(0)
提交回复
热议问题