在Tiny IOC中,如何得到它正在解析的类型。例如日志记录:TinyIOC构造函数注入
container.Register<ILogger>((c, p) =>
{
return LoggerFactory.CreateLog(typeofCALLER);
});
我想添加一个工厂来构建一个ILogger,但没有注入信息。
在Tiny IOC中,如何得到它正在解析的类型。例如日志记录:TinyIOC构造函数注入
container.Register<ILogger>((c, p) =>
{
return LoggerFactory.CreateLog(typeofCALLER);
});
我想添加一个工厂来构建一个ILogger,但没有注入信息。
在这种情况下,简单使用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<T>
只是一个“标记接口”,并有来自它“导出”:
public interface ILogger<T> : ILogger
{
}
的Consumer
类仍然需要依赖ILogger<Consumer>
,但ConcreteLogger<T>
会直接执行成员。
我没有看到更好的方法,特别是如果接口是固定的,因为它不是你自己的。我不认为有一种方法可以向TinyIoC询问它目前正在试图解决的类型,然后才能够采取行动,所以如果您需要类型特定的实现,则必须通过其他方式使类型变得通用 - 而泛型常常(并不总是)对此有帮助。
这真棒,有没有办法做到这一点,而不必将ILogger转换为泛型类型。我不想要这个,因为我想保持与log4net的记录器impl兼容。 – maxfridbe
您不需要更改'ILogger',但是如果没有泛型,您将无法完成。查看更新的答案。 – TeaDrivenDev
如果您尝试使用它,您可能已经注意到它实际上并不工作。这是因为TinyIoC在开放泛型方面存在一个错误:http://stackoverflow.com/questions/15450518/how-to-register-a-generic-interface-using-tinyioc/15714045 – TeaDrivenDev
注意:我在我的示例中使用了ILog
,这是log4net将其称为类型特定的记录器类。但它似乎是以与您的示例中的ILogger完全相同的方式创建和使用的,而log4net的LogManager.GetLog(Type t)
与您的LoggerFactory.CreateLog(typeofCALLER)
类似。
这是一个更多的工作,但您可以创建一个通用的工厂类,生成您的类型特定的记录器。将此工厂类注入构造函数而不是Ilog
。
TinyIoC的注册API不允许您指定一个工厂,它知道当前正在解析的类型被注入到的包含类型。由于TinyIoC注入了LogFactory<Foo>
或LogFactory<Bar>
的正确通用实例,然后我们捕获了由logFactory.Get()
返回的正确生成的ILog
实例,因此以下解决方法可行。除了使用autofac做了一些额外的按键操作 - 它确实支持你之后的操作 - 但它们并不需要太多的考虑。
假设你想在类Foo
和Bar
中做一些日志记录。您可以定义LogFactory<T>
只有一次,而在富,酒吧使用,并要求具有特定类型的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();
}
}
您在这里提供一点背景知识。 LoggerFactory的代码是什么样的,你的意思是什么样的“注入信息”?作为一个黑暗中的镜头,我认为没有静态的LoggerFactory(或者至少不是直接在这里调用)可能会有所帮助。 – TeaDrivenDev
LoggerFactory.CreateLog只是返回一个Ilogger,它是一个静态的或者是它的完成。我需要注入者的注入信息来填写typeofCALLER – maxfridbe
我认为它对我来说意味着什么 - LoggerFactory返回的实现取决于你想要注入ILogger实例的类,对吗? – TeaDrivenDev