在Tiny IOC中,如何获得正在解决的类型。例如记录:
container.Register<ILogger>((c, p) =>
{
return LoggerFactory.CreateLog(typeofCALLER);
});
我正在尝试添加工厂来构建ILogger,但没有注入信息。
答案 0 :(得分:2)
在这种情况下,简单地使用TinyIoC的Open Generics功能就足够了。
public class Consumer
{
public Consumer(ILogger<Consumer> logger) {}
}
public interface ILogger<T>
{
string Log(string message);
}
public class ConcreteLogger<T>:ILogger<T>
{
public string Log(string message)
{
return string.Format("{0}: {1}", typeof (T), message);
}
}
然后再做
container.Register(typeof (ILogger<>), typeof (ConcreteLogger<>));
这将导致ConcreteLogger<Consumer>
的实例被注入Consumer
构造函数。
修改强>
如果您需要ILogger
引用,则只需将ILogger<T>
设为“标记界面”,并将其从ILogger
“派生”:
public interface ILogger<T> : ILogger
{
}
Consumer
类仍然需要依赖ILogger<Consumer>
,但ConcreteLogger<T>
会直接实现ILogger
个成员。
我认为没有更好的方法,特别是如果ILogger
界面是固定的,因为它不是你自己的。我认为有一种方法可以向TinyIoC询问它当前正在尝试解决的类型,然后才能对其采取行动,因此如果您需要特定类型的实现,则必须通过其他方式了解类型 - 并且泛型经常(并非总是)对此有所帮助。
答案 1 :(得分:1)
注意:我在我的示例中使用ILog
,这就是log4net称之为特定类型的记录器类。但它似乎以与示例中的ILogger完全相同的方式创建和使用,并且log4net的LogManager.GetLog(Type t)
与您的LoggerFactory.CreateLog(typeofCALLER)
类似。
它可以做多一点工作,但您可以创建一个生成特定类型记录器的通用工厂类。将此工厂类注入构造函数而不是Ilog
。
TinyIoC的注册API不允许您指定一个工厂,该工厂知道正在注入当前解析类型的包含类型。以下解决方法有效,因为TinyIoC会注入LogFactory<Foo>
或LogFactory<Bar>
的正确通用实例,然后我们捕获ILog
返回的正确生成的logFactory.Get()
实例。一些额外的击键比我们使用autofac做的更多 - 这确实支持你所追求的 - 但他们不需要太多考虑。
假设您要在班级Foo
和Bar
中进行一些登录。您只需定义LogFactory<T>
一次,并在Foo,Bar和任何其他需要使用特定于类型的ILog实例进行日志记录的类中使用它:
public class LogFactory<T> {
public LogFactory() {} //empty
public ILog Get() { return LogManager.GetLogger(typeof(T)); }
}
public class Foo {
private readonly ILog _log;
public Foo(LogFactory<Foo> logFactory, ...) {
_log = logFactory.Get();
}
}
public class Bar{
private readonly ILog _log;
public Bar(LogFactory<Bar> logFactory, ...) {
_log = logFactory.Get();
}
}