Ric*_*ick 10 dependency-injection unity-container
我有一个具有多个实现的接口(称为IAcmeService).
FileSystemAcmeService
DatabaseAcmeService
NetworkAcmeService
Run Code Online (Sandbox Code Playgroud)
最终用户需要能够选择将使用哪种实现,并保存该选择.
目前我正在配置我的IOC容器(Unity)以使用名称注册所有已知的实现.
container.RegisterType(of IAcmeService, FileSystemAcmeService)("FileSystemAcmeService")
container.RegisterType(of IAcmeService, DatabaseAcmeService)("DatabaseAcmeService")
container.RegisterType(of IAcmeService, NetworkAcmeService)("NetworkAcmeService")
Run Code Online (Sandbox Code Playgroud)
为了允许用户保存他们的选择,我有app.config配置部分文件,用于存储要使用的所选服务名称.
要解决所选的实现,我正在使用该服务的类的Initialize方法中进行手动解析.
Private _service as IAcmeService
Public Sub Initialize()
_service = container.Resolve(of IAcmeService)(_config.AcmeServiceName)
End Sub
Run Code Online (Sandbox Code Playgroud)
这似乎不对,因为我的班级必须知道容器.但我无法想出另一种方式.
是否有其他方法可以让最终用户选择而不让班级知道容器?
定义和实现抽象工厂是解决此类问题的标准方法.如果你原谅我使用C#,你可以像这样定义一个IAcmeServiceFactory接口:
public interface IAcmeServiceFactory
{
IAcmeService Create(string serviceName);
}
Run Code Online (Sandbox Code Playgroud)
您现在可以编写一个类似这样的具体实现:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想能够创建任意数量的IAcmeService实例,你可以使它更通用,但我会把它作为练习留给读者:)
这将要求您也注册Factory with Unity.在任何需要基于名称的IAcmeService的地方,您依赖于IAcmeServiceFactory而不是IAcmeService本身.
| 归档时间: |
|
| 查看次数: |
3307 次 |
| 最近记录: |