使用自定义工具,您可以将组件的默认激活器更改为执行您想要的激活器。这是一个有效的解决方案:
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComponentCreater
{
public interface IWatchDogService
{
Type WatchingType { get; set; }
}
public class WatchDogService : IWatchDogService
{
public Type WatchingType { get; set; }
}
public class WatchedClassViaConstructor
{
private readonly IWatchDogService watchDogService;
public WatchedClassViaConstructor(IWatchDogService watchDogService)
{
this.watchDogService = watchDogService;
}
public void Print()
{
Console.WriteLine(this.watchDogService.WatchingType.Name);
}
}
public class WatchDogFacility : AbstractFacility
{
protected override void Init()
{
this.Kernel.ComponentModelCreated += Kernel_ComponentModelCreated;
}
private void Kernel_ComponentModelCreated(ComponentModel model)
{
model.CustomComponentActivator = typeof(WatchedComponentActivator);
}
}
public class WatchedComponentActivator : DefaultComponentActivator
{
public WatchedComponentActivator(ComponentModel model, IKernel kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction)
{
}
protected override object CreateInstance(CreationContext context, ConstructorCandidate constructor, object[] arguments)
{
object component = base.CreateInstance(context, constructor, arguments);
if (arguments != null)
{
IWatchDogService watchDogService = arguments.FirstOrDefault(arg => arg is IWatchDogService) as IWatchDogService;
if (watchDogService != null)
{
watchDogService.WatchingType = component.GetType();
}
}
return component;
}
}
class Program
{
static void Main(string[] args)
{
IWindsorContainer container = new WindsorContainer();
container.AddFacility<WatchDogFacility>();
container.Register(
Component.For<IWatchDogService>()
.ImplementedBy<WatchDogService>()
.LifestyleTransient(),
Component.For<WatchedClassViaConstructor>()
);
WatchedClassViaConstructor obj = container.Resolve<WatchedClassViaConstructor>();
obj.Print();
Console.ReadLine();
}
}
}
如果你喜欢 AOP 并且希望你的类保持整洁,你可以使用上面的稍微修改的版本,让你监视的类看起来像这样:
public class WatchedClassViaInheritance : WatchedClass
{
public void Print()
{
Console.WriteLine(this.WatchDogService.WatchingType.Name);
}
}
这使用相同的策略,但使用属性注入。我已经创建了一个组件模型构造贡献者来强制执行 Castle 要求注入 IWatchDogServcie,就像如果它是构造函数注入你需要做的那样。这是代码:
namespace ComponentCreater2
{
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.ModelBuilder;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IWatchDogService
{
Type WatchingType { get; set; }
}
public class WatchDogService : IWatchDogService
{
public Type WatchingType { get; set; }
}
public interface IIsWatched
{
IWatchDogService WatchDogService { get; set; }
}
public abstract class WatchedClass : IIsWatched
{
public IWatchDogService WatchDogService { get; set; }
}
public class WatchedClassViaInheritance : WatchedClass
{
public void Print()
{
Console.WriteLine(this.WatchDogService.WatchingType.Name);
}
}
public class WatchDogFacility : AbstractFacility
{
protected override void Init()
{
this.Kernel.ComponentModelCreated += Kernel_ComponentModelCreated;
this.Kernel.ComponentModelBuilder.AddContributor(new RequireWatchDogService());
}
private void Kernel_ComponentModelCreated(ComponentModel model)
{
if (typeof(IIsWatched).IsAssignableFrom(model.Implementation))
{
model.CustomComponentActivator = typeof(WatchedComponentActivator);
}
}
}
public class WatchedComponentActivator : DefaultComponentActivator
{
public WatchedComponentActivator(ComponentModel model, IKernel kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction)
{
}
protected override void SetUpProperties(object instance, CreationContext context)
{
base.SetUpProperties(instance, context);
IIsWatched watched = instance as IIsWatched;
if (watched != null)
{
watched.WatchDogService.WatchingType = instance.GetType();
}
}
}
public class RequireWatchDogService : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
model.Properties.Where(prop => prop.Dependency.TargetType == typeof(IWatchDogService))
.All(prop => prop.Dependency.IsOptional = false);
}
}
class Program2
{
static void Main(string[] args)
{
IWindsorContainer container = new WindsorContainer();
container.AddFacility<WatchDogFacility>();
container.Register(
Component.For<IWatchDogService>()
.ImplementedBy<WatchDogService>()
.LifestyleTransient(),
Component.For<WatchedClassViaInheritance>()
);
WatchedClassViaInheritance obj = container.Resolve<WatchedClassViaInheritance>();
obj.Print();
Console.ReadLine();
}
}
}