假设我有一个服务接口(interface):
public interface IFooService
{
void DoSomething();
}
以及通用服务的具体实现:
public class FooService<TRequestingClass> : IFooService
{
public virtual void DoSomething() { }
}
我还有其他一些需要 IFooService 实例的类:
public class Bar
{
private IFooService _fooService;
public Bar(IFooService fooService)
{
this._fooService = fooService;
}
}
我需要连接我的 IoC 容器,以便在创建 Bar 时向其传递 FooService
FooService
public class FooService : IFooService
{
public FooService(string requestingClassName) { }
}
如何连接我的 IoC 容器以这种方式构建依赖项?
如果您对为什么我想要这样一个奇怪的结构感到困惑,请考虑当您获得一个使用 log4net.LogManager.GetLogger(typeof(SomeClass)) 创建的 ILog 时,log4net 如何工作得最好。我不想在我的代码中引用 log4net,所以我想编写一个简单的 ILogger 接口(interface),并用类似这样的东西实现它:
public class GenericLogger<T> : ILogger
{
private readonly ILog log;
public GenericLogger()
{
this.log = log4net.LogManager.GetLogger(typeof(T));
}
public void Debug(object message)
{
this.log.Debug(message);
}
/* .... etc .... */
}
最佳答案
最简单的方法是创建一个 ILogger<T>
接口(interface):
public class ILogger<T> : ILogger { }
public class GenericLogger<T> : ILogger<T> { ... }
然后依靠泛型类型推断得到正确的类型。例如,在 Ninject 中,您只需要以下绑定(bind):
Bind(typeof(ILogger<>)).To(typeof(GenericLogger<>));
那么您的消费类型将如下所示:
public class FooService : IFooService {
public FooService(ILogger<FooService> logger) { ... }
}
如果您坚决反对 ILogger<T>
界面,您可以做一些更有创意的事情,比如自定义提供程序,它读取 IContext
确定父类型。
public class GenericLogger : ILogger {
public class GenericLogger(Type type) { ... }
}
public class LoggerProvider : Provider<ILogger> {
public override ILogger CreateInstance(IContext context) {
return new GenericLogger(context.Target.Member.ReflectedType);
}
}
然后消费类型会像这样工作:
public class FooService : IFooService {
public FooService(ILogger logger) { ... }
}
关于c# - 使用 Ninject(或其他一些容器)我如何找出请求服务的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/719346/