Я пытаюсь присоединить обработчик событий Activated
к Components
, который реализует определенный интерфейс.
Я хочу сделать это в одном месте глобально, и мне не нужно вызывать метод для каждогопостановка на учет.то есть OnActivation не подходит, так как это вызов для каждой регистрации.
Для этого у меня есть RegisterBuildCallback
, который зацикливается на ComponentRegistry.Registrations
, присоединяясь к событию Activated
, где это необходимо.
Проблема, которую я обнаружил, заключается в том, что Components
, помеченный как AutoActivate
, активируется до запуска RegisterBuildCallback
.Так что Activated
не вызывается для AutoActivate
Components
, или, скорее, вызывается до того, как я прикрепил обработчик событий.
AutoActivate
работает, как предполагалось, и как описано в документации:
Автоматически активируемый компонент - это компонент, который просто необходимо активировать один раз при сборке контейнера .
https://autofaccn.readthedocs.io/en/latest/lifetime/startup.html#auto-activated-components
Вот MCVE:
using System;
using System.Linq;
using Autofac;
namespace AutofacActivatedNotCalled
{
public interface ISomething { }
public interface IFoo { }
public interface IBar { }
public class Foo : IFoo, ISomething { }
public class Bar : IBar, ISomething { }
public class Baz { public Baz(IFoo foo) { } }
class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// Add callback which hooks up Activated event.
builder
.RegisterBuildCallback(builtContainer =>
{
var iSomethingRegistrations = builtContainer
.ComponentRegistry
.Registrations
.Where(registration => IsISomething(registration.Activator.LimitType))
.ToList();
Console.WriteLine($"Found {iSomethingRegistrations.Count} ISomething Registrations");
foreach (var iSomethingRegistration in iSomethingRegistrations)
{
Console.WriteLine($"ISomething {iSomethingRegistration.Activator.LimitType.Name} Add Activated");
iSomethingRegistration.Activated += (sender, eventArgs) =>
{
Console.WriteLine($"ISomething {eventArgs.Instance.GetType().Name} Activated");
};
}
});
// Register services
builder.RegisterType<Foo>().As<IFoo>().SingleInstance();
builder
.RegisterType<Bar>()
.As<IBar>()
.SingleInstance()
.AutoActivate()
.OnActivated(eventArgs => Console.WriteLine($"IBar Activated"));
builder.RegisterType<Baz>();
// Build container
var container = builder.Build();
// Resolve service
var baz = container.Resolve<Baz>();
Console.ReadLine();
}
private static bool IsISomething(Type type)
=> (type == typeof(ISomething))
|| type.GetInterfaces().Any(interfaceType => interfaceType == typeof(ISomething));
}
}
Вот вывод:
IBar Activated
Found 2 ISomething Registrations
ISomething Foo Add Activated
ISomething Bar Add Activated
ISomething Foo Activated
Как уже упоминалось, я стараюсь избегать использования OnActivated
при регистрации Component
.Он включен в пример, чтобы показать, что Activate
запускается, но до запуска RegisterBuildCallback
.
Есть ли способ обработать AutoActivated
Components
с моим подходом?