[英]Access or get Autofac Container inside a static class
我需要在靜態類中獲取或訪問我的IoC容器。 這是我的(簡化)場景:
我在一個Startup類中注冊ASP .net Web Api的依賴項(但我也是為MVC或WCF注冊的。我有一個DependecyResolver項目,但為了簡單起見,請考慮以下代碼)
// Web Api project - Startup.cs
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
var builder = new ContainerBuilder();
// ... Omited for clarity
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.AsClosedTypesOf(typeof(IHandle<>))
.AsImplementedInterfaces();
// ...
IContainer container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
}
然后,在一個單獨的類庫中,我有我的靜態類(為了清晰起見,再次簡化):
public static class DomainEvents
{
private static IContainer Container { get; set; }
static DomainEvents()
{
//Container = I need get my Autofac container here
}
public static void Register<T>(Action<T> callback) where T : IDomainEvent { /* ... */ }
public static void ClearCallbacks() { /* ... */ }
public static void Raise<T>(T args) where T : IDomainEvent
{
foreach (var handler in Container.Resolve<IEnumerable<IHandle<T>>>())
{
handler.Handle(args);
}
// ...
}
}
知道我怎么能得到這個?
我需要在靜態類中獲取或訪問我的IoC容器。 知道我怎么能得到這個?
是的,你沒有! 認真。 具有靜態DomainEvents
類的模式源自Udi Dahan,但即使是Udi也承認這是一個糟糕的設計。 需要自己依賴的靜態類非常難以使用。 它們使系統難以測試和維護。
相反,創建一個IDomainEvents
抽象,並將該抽象的實現注入需要發布事件的類中。 這完全解決了您的問題。
您可以按如下方式定義DomainEvents
類:
public interface IDomainEvents
{
void Raise<T>(T args) where T : IDomainEvent;
}
// NOTE: DomainEvents depends on Autofac and should therefore be placed INSIDE
// your Composition Root.
private class AutofacDomainEvents : IDomainEvents
{
private readonly IComponentContext context;
public AutofacDomainEvents(IComponentContext context) {
if (context == null) throw new ArgumentNullException("context");
this.context = context;
}
public void Raise<T>(T args) where T : IDomainEvent {
var handlers = this.context.Resolve<IEnumerable<IHandle<T>>>();
foreach (var handler in handlers) {
handler.Handle(args);
}
}
}
您可以按如下方式注冊此課程:
IContainer container = null;
var builder = new ContainerBuilder();
builder.RegisterType<AutofacDomainEvents>().As<IDomainEvent>()
.InstancePerLifetimeScope();
// Other registrations here
container = builder.Build();
您可以在DomainEvents
類中創建一個靜態方法來注入容器,如下所示:
public static class DomainEvents
{
public static void SetContainer(IContainer container)
{
Container = container;
}
....
}
然后從ASP.NET應用程序中調用此方法來注入容器:
DomainEvents.SetContainer(container);
請注意,我將直接回答您的問題。 但是,我在這里看到了一些問題:
只有應用程序應具有組合根。 圖書館和框架不應該。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.