Unity IoC - ComponentCreated / OnActivating / RegisterInitializer 事件
Unity IoC - ComponentCreated / OnActivating / RegisterInitializer events
我正在使用 Microsoft Unity IOC 容器,我希望能够在每次创建(未注册)组件时引发事件,即生命周期事件
例如
- 在 Castle Windosor 他们有
ComponentCreated
事件。
- 在 Autofac 中,他们有生命周期事件
OnActivating
和 OnRelease
事件。
- 在 Simple Injector 中,他们有
RegisterInitializer
和 Options.RegisterResolveInterceptor
方法。
- 等..
Unity 中的等价物是什么?
开箱即用的 Unity 没有通知。但是,Unity 提供了使用 UnityContainerExtension
扩展容器功能的能力,这让您可以相当轻松地添加通知。
容器可以在多个阶段通过指定 UnityBuildStage
的哪一部分扩展到 运行 来连接到构建管道(阶段是设置、类型映射、生命周期, PreCreation, Creation, Initialization, PostInitialization)。 (这可能会有点棘手,因为管道可能会短路,就像使用 'singleton' ContainerControlledLifetimeManager
管道在生命周期停止的情况一样。)
在容器扩展中已经有两个通知注册的事件:Registering
和 RegisteringInstance
。如果您关心注册,这些可能会有用。
如果你想在对象被解析或拆除时收到通知,那么你可以编写一个类似于这样的容器扩展:
public class BuildNotificationExtension : UnityContainerExtension
{
public event EventHandler<NamedTypeBuildKey> BuiltUp;
public event EventHandler<object> TearDown;
protected override void Initialize()
{
var builderAwareStrategy = new CustomBuilderAwareStrategy(this.BuiltUp, this.TearDown);
// Run before Lifetime so we know about all resolved calls
// even if singleton that is not actually built up
base.Context.Strategies.Add(builderAwareStrategy, UnityBuildStage.TypeMapping);
}
private class CustomBuilderAwareStrategy : BuilderStrategy
{
private event EventHandler<NamedTypeBuildKey> BuiltUp;
private event EventHandler<object> TearDown;
public CustomBuilderAwareStrategy(EventHandler<NamedTypeBuildKey> builtUp,
EventHandler<object> tearDown)
{
this.BuiltUp = builtUp;
this.TearDown = tearDown;
}
public override void PreBuildUp(IBuilderContext context)
{
this.BuiltUp?.Invoke(this, context.BuildKey);
}
public override void PreTearDown(IBuilderContext context)
{
this.TearDown?.Invoke(this, context.Existing);
}
}
}
如果您 运行 这个控制台应用程序:
class Program
{
private class Foo {}
private interface ILogger { }
private class Logger : ILogger
{
public Logger(Foo foo1, Foo foo2) { }
}
static void Main(string[] args)
{
var buildNotificationExtension = new BuildNotificationExtension();
buildNotificationExtension.BuiltUp += (sender, key) =>
{
Console.WriteLine($"Built up type '{key.Type.Name}' with name '{key.Name}'.");
};
buildNotificationExtension.TearDown += (sender, obj) =>
{
Console.WriteLine($"Tear down type '{obj.GetType().Name}'.");
};
IUnityContainer container = new UnityContainer()
.AddExtension(buildNotificationExtension)
// Register ILogger as singleton
.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
var logger = container.Resolve<ILogger>();
var anotherLogger = container.Resolve<ILogger>();
container.Teardown(logger);
}
}
您将收到以下输出:
Built up type 'Logger' with name ''.
Built up type 'Foo' with name ''.
Built up type 'Foo' with name ''.
Built up type 'Logger' with name ''.
Tear down type 'Logger'.
显示第一个 Logger
已解决,导致两个 Foo
实例被解决。然后 Logger
再次解析,但由于它是单例,因此返回当前 Logger
实例并且没有实例化新的 Foo
实例。最后Logger
被拆了
此方法可用于向 Unity 处理管道的不同阶段添加额外的通知。例如您可以修改 BuildNotificationExtension
class 以接受多个阶段并向每个阶段添加通知。
我正在使用 Microsoft Unity IOC 容器,我希望能够在每次创建(未注册)组件时引发事件,即生命周期事件
例如
- 在 Castle Windosor 他们有
ComponentCreated
事件。 - 在 Autofac 中,他们有生命周期事件
OnActivating
和OnRelease
事件。 - 在 Simple Injector 中,他们有
RegisterInitializer
和Options.RegisterResolveInterceptor
方法。 - 等..
Unity 中的等价物是什么?
开箱即用的 Unity 没有通知。但是,Unity 提供了使用 UnityContainerExtension
扩展容器功能的能力,这让您可以相当轻松地添加通知。
容器可以在多个阶段通过指定 UnityBuildStage
的哪一部分扩展到 运行 来连接到构建管道(阶段是设置、类型映射、生命周期, PreCreation, Creation, Initialization, PostInitialization)。 (这可能会有点棘手,因为管道可能会短路,就像使用 'singleton' ContainerControlledLifetimeManager
管道在生命周期停止的情况一样。)
在容器扩展中已经有两个通知注册的事件:Registering
和 RegisteringInstance
。如果您关心注册,这些可能会有用。
如果你想在对象被解析或拆除时收到通知,那么你可以编写一个类似于这样的容器扩展:
public class BuildNotificationExtension : UnityContainerExtension
{
public event EventHandler<NamedTypeBuildKey> BuiltUp;
public event EventHandler<object> TearDown;
protected override void Initialize()
{
var builderAwareStrategy = new CustomBuilderAwareStrategy(this.BuiltUp, this.TearDown);
// Run before Lifetime so we know about all resolved calls
// even if singleton that is not actually built up
base.Context.Strategies.Add(builderAwareStrategy, UnityBuildStage.TypeMapping);
}
private class CustomBuilderAwareStrategy : BuilderStrategy
{
private event EventHandler<NamedTypeBuildKey> BuiltUp;
private event EventHandler<object> TearDown;
public CustomBuilderAwareStrategy(EventHandler<NamedTypeBuildKey> builtUp,
EventHandler<object> tearDown)
{
this.BuiltUp = builtUp;
this.TearDown = tearDown;
}
public override void PreBuildUp(IBuilderContext context)
{
this.BuiltUp?.Invoke(this, context.BuildKey);
}
public override void PreTearDown(IBuilderContext context)
{
this.TearDown?.Invoke(this, context.Existing);
}
}
}
如果您 运行 这个控制台应用程序:
class Program
{
private class Foo {}
private interface ILogger { }
private class Logger : ILogger
{
public Logger(Foo foo1, Foo foo2) { }
}
static void Main(string[] args)
{
var buildNotificationExtension = new BuildNotificationExtension();
buildNotificationExtension.BuiltUp += (sender, key) =>
{
Console.WriteLine($"Built up type '{key.Type.Name}' with name '{key.Name}'.");
};
buildNotificationExtension.TearDown += (sender, obj) =>
{
Console.WriteLine($"Tear down type '{obj.GetType().Name}'.");
};
IUnityContainer container = new UnityContainer()
.AddExtension(buildNotificationExtension)
// Register ILogger as singleton
.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
var logger = container.Resolve<ILogger>();
var anotherLogger = container.Resolve<ILogger>();
container.Teardown(logger);
}
}
您将收到以下输出:
Built up type 'Logger' with name ''.
Built up type 'Foo' with name ''.
Built up type 'Foo' with name ''.
Built up type 'Logger' with name ''.
Tear down type 'Logger'.
显示第一个 Logger
已解决,导致两个 Foo
实例被解决。然后 Logger
再次解析,但由于它是单例,因此返回当前 Logger
实例并且没有实例化新的 Foo
实例。最后Logger
被拆了
此方法可用于向 Unity 处理管道的不同阶段添加额外的通知。例如您可以修改 BuildNotificationExtension
class 以接受多个阶段并向每个阶段添加通知。