我有以下代碼:我是否需要將synclock與使用單例作用域的DI容器管理的對象一起使用?
public class DotLessFactory
{
private LessEngine lessEngine;
public virtual ILessEngine GetEngine()
{
return lessEngine ?? (lessEngine = CreateEngine());
}
private ILessEngine CreateEngine()
{
var configuration = new LessConfiguration();
return new LessFactory().CreateEngine(configuration);
}
}
假設如下:
- 我總是想返回ILessEngine的同一個實例。
- 我使用DI容器(我將使用此示例中的StructureMap)來管理我的對象。
- 由於假設編號1,我的對象的生命週期將是Singleton。
- CreateEngine中的代碼執行通過NuGet包引用的代碼。
- DotLess僅僅是一個例子。此代碼可適用於任何類似的NuGet包。
方法1
註冊我的目標和我的DI容器使用:
For<DotLessFactory>().Singleton().Use<DotLessFactory>();
For<ILessEngine>().Singleton().Use(container => container.GetInstance<DotLessFactory>().GetEngine());
For<ISomeClass>().Singleton().Use<SomeClass>();
現在我可以ILessEngine添加到構造函數,有我的容器注入它的一個實例爲每碼下面。
public class SomeClass : ISomeClass
{
private ILessEngine lessEngine;
public SomeClass(ILessEngine lessEngine)
{
this.lessEngine = lessEngine;
}
}
方法2
介紹的IDotLessFactory接口暴露所述GetEngine方法。註冊我的目標和我的DI容器使用:
For<IDotLessFactory>().Singleton().Use<DotLessFactory>();
For<ISomeClass>().Singleton().Use<SomeClass>();
現在,我廠將創造ILessEngine實例按下面的代碼。
public class SomeClass : ISomeClass
{
private ILessEngine lessEngine;
public SomeClass(IDotLessFactory factory)
{
Factory = factory;
}
public IDotLessFactory Factory { get; private set; }
public ILessEngine LessEngine
{
get
{
return lessEngine ?? (lessEngine = Factory.GetEngine());
}
}
}
我的問題是:
- 是什麼,當談到ILessEngine方法1和2之間的根本區別?在方法1中,ILessEngine由容器管理,在方法2中不是。每種方法的優缺點是什麼?一種方法比另一種更好嗎?
- 我是否需要在CreateEngine方法中使用synclock以確保任何方法的線程安全?什麼時候應該/不應該在這種情況下使用synclock?
- 我見過Activator.CreateInstance在CreateEngine方法內部使用的例子,而不是直接創建對象。有沒有人會使用這種方法的原因?有沒有在工廠對象中引入直接依賴關係到NuGet包內的對象?
- 我們假設被引用的NuGet包在HttpContext下工作。在單身作用域中註冊我的工廠對HttpContext有任何負面影響,或者這並不重要,因爲我認爲NuGet包很可能管理HttpContext本身的範圍?
- 最後,DotLessFactory最終將與Bundles(Microsoft.AspNet.Web.Optimization NuGet包)一起使用,並且Bundle僅在Application Start上實例化(不由容器管理)。 Bundle將取決於DotLessFactory的注入實例。這個事實對上述問題有什麼影響嗎?
任何反饋將非常有幫助。