and*_*ecu 6 c# dependency-injection factory-pattern
试图找出如何最好地处理以下场景:
假设一个RequestContext依赖于外部服务的类,例如:
public class RequestContext : IRequestContext
{
private readonly ServiceFactory<IWeatherService> _weatherService;
public RequestContext(ServiceFactory<IWeatherService> weatherService, UserLocation location, string query)
{
_weatherService = weatherService;
...
Run Code Online (Sandbox Code Playgroud)
我应该在最终实例化的类中需要什么样的依赖RequestContext?它可能是ServiceFactory<IWeatherService>,但这似乎不对,或者我可以创建一个IRequestContextFactory以下的线:
public class RequestContextFactory : IRequestContextFactory
{
private readonly ServiceFactory<IWeatherService> _weatherService;
public RequestContextFactory(ServiceFactory<IWeatherService> weatherService)
{
_weatherService = weatherService;
}
public RequestContext Create(UserLocation location, string query)
{
return new RequestContext(_weatherService, location, query);
}
}
Run Code Online (Sandbox Code Playgroud)
然后传递IRequestContextFactory构造函数注入.
这似乎是一种很好的方法,但这种方法的问题在于我认为它阻碍了可发现性(开发人员必须了解工厂并实施它,这并不是很明显).
我错过了更好/更可发现的方式吗?
松散耦合的美妙之处在于我们可以不断隐藏之前的细节.
从IRequestContext的消费者的角度来看,RequestContext及其依赖关系的存在纯粹是一个实现细节.由于Liskov替换原则,消费者必须只处理IRequestContext:
public class MyClass
{
private readonly IRequestContext reqCtx;
public MyClass(IRequestContext reqCtx)
{
if (reqCtx == null)
{
throw new ArgumentNullException("reqCtx");
}
this.reqCtx = reqCtx;
}
// Implement using this.reqCtx...
}
Run Code Online (Sandbox Code Playgroud)
只有在应用程序的Composition Root中,您才需要最终将所有内容连接在一起.这是一个穷人的DI方法草图:
ServiceFactory<IWeatherService> weatherService =
new ServiceFactory<IWeatherService>();
UserLocation location = new UserLocation;
string query = "foo";
IRequestContext reqCtx = new RequestContext(weatherService, location, query);
var mc = new MyClass(reqCtx);
Run Code Online (Sandbox Code Playgroud)