Jos*_*nge 5 c# dependency-injection ioc-container autofac 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);
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后,在一个单独的类库中,我有我的静态类(为了清晰起见,再次简化):
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);
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
知道我怎么能得到这个?
我需要在静态类中获取或访问我的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式注册此课程:
IContainer container = null;
var builder = new ContainerBuilder();
builder.RegisterType<AutofacDomainEvents>().As<IDomainEvent>()
.InstancePerLifetimeScope();
// Other registrations here
container = builder.Build();
Run Code Online (Sandbox Code Playgroud)
您可以在DomainEvents类中创建一个静态方法来注入容器,如下所示:
public static class DomainEvents
{
public static void SetContainer(IContainer container)
{
Container = container;
}
....
}
Run Code Online (Sandbox Code Playgroud)
然后从ASP.NET应用程序中调用此方法来注入容器:
DomainEvents.SetContainer(container);
Run Code Online (Sandbox Code Playgroud)
请注意,我将直接回答您的问题.但是,我在这里看到了一些问题:
只有应用程序应具有组合根.图书馆和框架不应该.
| 归档时间: |
|
| 查看次数: |
16487 次 |
| 最近记录: |