在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