dependency injection - How to Resolve type based on end-user configuration value? -
Text after "
I have an interface (this is called IAcmeService) which is more than one implementation.
FileSystemAcmeService DatabaseAcmeService has to be able to select the network termination
The end user will use which implementation will be used and also save that selection.
Currently I have to register all known implemenatation with my IoC container (Unity) one name. ("DatabaseAcmeService") container ("NetworkAcmeService") (IAcmeService, NetworkAcmeService) of container.RegisterType (IAcmeService, FileSystemAcmeService) ("FileSystemAcmeService") container.RegisterType (IAcmeService, DatabaseAcmeService) .RegisterType
In order to protect users' selection, I store the app.config configuration section using the chosen service name. To allow
To resolve the selected implementation, I am revising a manual in the initial method of the class that uses the service.
<> IAcmeService Public Sub Initialize () _service = container.Resolve (IAcmeService's) (_config.AcmeServiceName) End Sub This It does not look right because my class needs to know about the container but I can not understand another method.
What else to allow end-user selection without the class knowing about the container Are the ways >
Defining and implementing is the standard solution to this type of problem. If you forgive your use of C #, you can define the IAcmeServiceFactory interface like this:
Public Interface IAcmeServiceFactory {IAcmeService Build (string serviceName); }
You can now write a solid implementation of this type:
public class AcmeServiceFactory: IAcmeServiceFactory {Private only read IAcmeService fsService; Private Readonly IAcmeService dbService; Private Readonly IAcmeService nwService; Public AcmeServiceFactory (IAcmeService fsService, IAcmeService dbService, IAcmeService nwService) {if (fsService == faucet) {New ArgumentNullException ("fsService"); } If (dbService == faucet) {New argument NullException ("dbService"); } If (nwService == faucet) {New argument NullException ("nwService"); } This.fsService = fsService; This.dbService = dbService; This.nwService = nwService; } Create public IAcmeService (string serviceName) {switch case serviceName {case "fs": return.fsService; Case "DB": Return to the DBS service; Case "NW": return it. NwService; Case default: throwing new argument options ("savannum"); }}}
If you want to be able to create an arbitrary number of IAcmeService instances, you can make it more general purpose, but I get it as an exercise form for the reader
For this, you have to register the factory with unity. At any place where you require IAcmeService based on the name, you take dependency on IAcmeServiceFactory instead of IAcmeService.
Comments
Post a Comment