次のことを考慮してください
builder.Register(c => new A());
builder.Register(c => new B());
builder.Register(c => new C());
B
とC
はどちらもISomeInterface
です。
ここで、IEnumerable
を実装するすべての登録済みオブジェクトのISomeInterface
を取得したいと思います。
Autofacでこれをどのように達成できますか?
これを試しただけで、機能し、ライフタイムのコンテキストに依存しません。
代わりにActivatorを使用してタイプを列挙します
var types = con.ComponentRegistry.Registrations
.Where(r => typeof(ISomeInterface).IsAssignableFrom(r.Activator.LimitType))
.Select(r => r.Activator.LimitType);
次に解決するには:
IEnumerable<ISomeInterface> lst = types.Select(t => con.Resolve(t) as ISomeInterface);
あなたが持っている場合
container.Register(c => new A()).As<ISomeInterface>();
container.Register(c => new B()).As<ISomeInterface>();
それからあなたがするとき
var classes = container.Resolve<IEnumerable<ISomeInterface>>();
AとBを含むISomeInterfaceのリストである変数を取得します
これが私がそれをした方法です。
var l = Container.ComponentRegistry.Registrations
.SelectMany(x => x.Services)
.OfType<IServiceWithType>()
.Where(x =>
x.ServiceType.GetInterface(typeof(ISomeInterface).Name) != null)
.Select(c => (ISomeInterface) c.ServiceType);
継承されたクラスに関してこれを検索している人のための明確化
例:
public static IEnumerable<Type> GetTypesInherit<T>(this Assembly assembly)
{
var types = Assembly.GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T)))
.ToList();
return types;
}
インストーラー:
public static IContainer Install()
{
var builder = new ContainerBuilder();
var executingAssembly = Assembly.GetExecutingAssembly();
var testScreens = executingAssembly.GetTypesInherit<TestScreen>();
foreach (var testScreen in testScreens)
{
builder.RegisterType(testScreen).As<TestScreen>();
}
var container = builder.Build();
return container;
}
使用法(暗黙的):
public class MainViewModel(IEnumerable<TestScreen> testScreens)
{}
いくつかのコンテキストに基づいて解決する必要がありました。わずかな違い...
builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(ISomeStrategy)))
.Where(t => typeof(ISomeStrategy).IsAssignableFrom(t))
.AsSelf();
builder.Register<Func<SomeEnum, ISomeStrategy>>(c =>
{
var types = c.ComponentRegistry.Registrations
.Where(r => typeof(ISomeStrategy).IsAssignableFrom(r.Activator.LimitType))
.Select(r => r.Activator.LimitType);
ISomeStrategy[] lst = types.Select(t => c.Resolve(t) as ISomeStrategy).ToArray();
return (someEnum) =>
{
return lst.FirstOrDefault(x => x.CanProcess(someEnum));
};
});
次に、戦略を使用してクラスを作成します
public SomeProvider(Func<SomeType, ISomeStrategy> someFactory)
{
_someFactory = someFactory;
}
public void DoSomething(SomeType someType)
{
var strategy = _someFactory(someType);
strategy.DoIt();
}