簡體   English   中英

是否可以從Autofac容器構建器中刪除現有注冊?

[英]Is it possible to remove an existing registration from Autofac container builder?

這些方面的東西:

builder.RegisterType<MyType>().As<IType>();
builder.RegisterType<MyType2>().As<IType>();
builder.DeRegisterType<MyType>().As<IType>()

var container = builder.Build();
var types = container.Resolve<IEnumerable<IType>>();
Assert.IsTrue(types.Count == 1);
Assert.IsTrue(types[0].GetType == typeof(MyType2));

場景:我經歷了一堆程序集,當我注冊類型時,我想確保我只有一個給定類型的實現。 我需要在創建容器之前執行此操作。 我可以自己跟蹤,但如果Autofac可以幫助我,那將會很好。

這不能直接使用ContainerBuilder來完成,除非你重新開始使用它。 請注意,首先構建一個容器,您應該能夠構建一個新容器,過濾掉不需要的類型並重用第一個容器中的注冊。 像這樣:

...
var container = builder.Build();

builder = new ContainerBuilder();
var components = container.ComponentRegistry.Registrations
                    .Where(cr => cr.Activator.LimitType != typeof(LifetimeScope))
                    .Where(cr => cr.Activator.LimitType != typeof(MyType));
foreach (var c in components)
{
    builder.RegisterComponent(c);
}

foreach (var source in container.ComponentRegistry.Sources)
{
    cb.RegisterSource(source);
}

container = builder.Build();

這不是很優雅,但它的工作原理。 現在,如果您可以詳細說明為什么要這樣做,也許有更好的方法。

Peter L.可能是最直接的選擇。

要完全解決問題,您是否可以修改發現組件的方式,以便在注冊之前對其進行過濾? 似乎必須有一種方法可以解決這個問題......這也可能是一個挑戰,以確定哪些組件要保留哪些組件以及要刪除哪些組件。

更復雜的方法是覆蓋IEnumerable支持以過濾掉您不想要的東西。 即復制並修改此代碼以創建FilteredCollectionSource ,其中排除了您不想要的組件。

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService);

會成為:

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService)
    .Where(reg => /* not a duplicate */);

如果使用RegisterSource()FilteredCollectionSource添加到構建器,則應該使用它而不是內置的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM