2

我有大量取决于看门狗组件的类。我向看门狗实例添加了对依赖类的引用。

目前我使用以下代码来完成此操作。

   class MyClass {
      public MyClass(IWatchDog watchDog) {
        watchDog.WatchingType = typeof(MyClass);
      }
   }

我的安装程序:

class IoC: IWindsorInstaller {
    public void Install(IWindsorContainer container, IConfigurationStore store) {
        container.Register(Component.For<MyClass>());
        container.Register(Component.For<IWatchDog>().ImplementedBy<WatchDogService>());
    }
}

是否可以让安装人员为我完成这项任务?这是我在伪代码中的想法, OnResolving 是我的想象方法:

class IoC : IWindsorInstaller {
    public void Install(IWindsorContainer container, IConfigurationStore store) {
        container.Register(Component.For<MyClass>());
        container.Register(
            Component.For<IWatchDog>()
                .ImplementedBy<WatchDogService>()
                .OnResolving<IWatchDog>(
                    new Action((Type typeBeingResolved, IWatchDog instance) =>
                        instance.WatchingType = typeBeingResolved));

    }
}

所以在这种情况下,我想typeBeingResolved会等于typeof(MyClass)ifcontainer.Resolve<MyClass>()被调用,或者null如果有人调用container.Resolve<IWatchDog>().

显然,如果我能以某种方式访问​​正在解析的类型的实例,OnCreate()那也可以。

4

1 回答 1

4

使用自定义工具,您可以将组件的默认激活器更改为执行您想要的激活器。这是一个有效的解决方案:

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();
    }
}

}

于 2013-11-09T05:25:18.753 回答