Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一些castle组件的运行时设置很困难_C#_.net_Inversion Of Control_Castle Windsor - Fatal编程技术网

C# 一些castle组件的运行时设置很困难

C# 一些castle组件的运行时设置很困难,c#,.net,inversion-of-control,castle-windsor,C#,.net,Inversion Of Control,Castle Windsor,我的问题(我认为)可以简单地用这个问题来描述: 如何让“管理器”类拥有一个特定接口的所有可能的具体实现的列表,该接口已注册为注入到其中的组件,以便可以对其进行迭代?(由于恼人的体系结构原因,我无法使用app.config注册我的组件,所以我猜只有运行时注册) 编辑: 啊哈!-发现我可以使用以下方式传入自己的配置文件: var container = new WindsorContainer(new XmlInterpreter("filename")); 所以-我可以使用我在下面提到的xml配

我的问题(我认为)可以简单地用这个问题来描述:

如何让“管理器”类拥有一个特定接口的所有可能的具体实现的列表,该接口已注册为注入到其中的组件,以便可以对其进行迭代?(由于恼人的体系结构原因,我无法使用app.config注册我的组件,所以我猜只有运行时注册)

编辑:
啊哈!-发现我可以使用以下方式传入自己的配置文件:

var container = new WindsorContainer(new XmlInterpreter("filename"));
所以-我可以使用我在下面提到的xml配置路径-这意味着我不必担心子对象的实例化,因为它们在我的现实生活中已经注入了依赖项

编辑:




不过,为了帮助您理解我的问题,我在下面列出了一个简单的副本,显示我的困惑!(请原谅这个可怕的领域概念!)

这是一个简单的控制台应用程序,它有一个管理器,可以在给定的对象列表上运行操作

代码:

public class Program {
    public static void Main() {
        var container = new WindsorContainer(new XmlInterpreter());
        var manager = container.Resolve<AnimalManager>();
        manager.PokeAnimals();
        container.Release(manager);
    }
}

public interface IMakeNoise {
    void MakeNoise();
}

public class Cat : IMakeNoise {
    public void MakeNoise() {
        Console.WriteLine("Meow");
    }
}

public class Dog : IMakeNoise {
    public void MakeNoise() {
        Console.WriteLine("Woof");
    }
}

public class AnimalManager {
    private readonly IList<IMakeNoise> noisemakers = new List<IMakeNoise>();

    public AnimalManager(IList<IMakeNoise> noisemakers) {
        this.noisemakers = noisemakers;
    }

    public void PokeAnimals() {
        foreach (var noisemaker in noisemakers) {
            noisemaker.MakeNoise();
        }
    }
}
公共类程序{
公共静态void Main(){
var container=新的WindsorContainer(新的XML解释器());
var manager=container.Resolve();
manager.PokeAnimals();
集装箱放行(经理);
}
}
公共接口IMakeNoise{
void MakeNoise();
}
公共类猫:伊玛肯诺{
公共场所噪音(){
控制台。书写线(“喵喵”);
}
}
公家犬:伊玛肯诺瓦犬{
公共场所噪音(){
控制台。书写线(“Woof”);
}
}
公共类AnimalManager{
private readonly IList noisemakers=new List();
公共动物管理员(IList noisemakers){
this.noisemakers=noisemakers;
}
公共空间PokeAnimals(){
foreach(noisemakers中的var noisemaker){
noisemaker.MakeNoise();
}
}
}
使用的配置文件类似于:


${Cat}
${Dog}

我的问题:

以上都很好。但是我不能在xml配置文件中定义我有哪种噪声发生器。直到运行时我才知道我有一只猫、一只狗、两只猫和一条金鱼或者其他什么

下面的代码最好地描述了我能看到的唯一方法。问题是,我必须实例化我的噪音制造者:“狗”和“猫”。这似乎是错误的,与Castle相反,在我的实际例子中,这是我真的不想做的事情。那么我做错了什么?我怎么才能得到一个“经理”类以获得特定接口的所有可能的具体实现的列表,这些实现已注册为注入到接口中的组件,以便可以对其进行迭代?

        var container = new WindsorContainer();

        container.AddComponent("Dog", typeof(IMakeNoise), typeof(Dog));
        container.AddComponent("Cat", typeof(IMakeNoise), typeof(Cat));
        container.AddComponent(
            "AnimalManager", typeof(AnimalManager), typeof(AnimalManager)
            );

        IList<IMakeNoise> noisemakers = new List<IMakeNoise> {new Dog(), new Cat()};

        var manager = container.Resolve<AnimalManager>(
            new Hashtable { { "noisemakers", noisemakers } }
            );

        manager.PokeAnimals();
        container.Release(manager);
var容器=新的WindsorContainer();
container.AddComponent(“Dog”,typeof(IMakeNoise),typeof(Dog));
container.AddComponent(“Cat”,类型为(IMakeNoise),类型为(Cat));
container.AddComponent(
“AnimalManager”,typeof(AnimalManager),typeof(AnimalManager)
);
IList noisemakers=新列表{new Dog(),new Cat()};
var manager=container.Resolve(
新哈希表{{“noisemakers”,noisemakers}
);
manager.PokeAnimals();
集装箱放行(经理);

下面类似的内容如何,这允许我注册接口“IAnimal”的每个实现,然后使用“ResolveAll”将所有实现作为集合返回

希望能有帮助

奥利

类程序
{
静态void Main(字符串[]参数)
{
var container=新的WindsorContainer();
container.Register(AllTypes.Pick().fromsassembly(Assembly.getExecutionGassembly()).AllowMultipleMatches());
var dog=container.Resolve();
var=container.ResolveAll();
}
}
公共接口IAnimal
{
}
公家犬:IAnimal
{
}
公共类Cat:IAnimal
{
}
公共级鱼类:IAnimal
{
}

最简单的方法是实现一个SubDependencyResolver来解析数组,然后在构造函数中传入类型

取自

公共类ArrayResolver:ISubDependencyResolver
{
私有只读IKernel内核;
公共阵列Resolver(IKernel内核)
{
this.kernel=内核;
}
公共对象解析(CreationContext上下文,ISubDependencyResolver parentResolver,
组件模型,
依赖项(模型依赖项)
{
返回kernel.ResolveAll(dependency.TargetType.GetElementType(),null);
}
public bool CanResolve(CreationContext上下文,ISubDependencyResolver parentResolver,
组件模型,
依赖项(模型依赖项)
{
返回dependency.TargetType!=null&&
dependency.TargetType.IsArray&&
dependency.TargetType.GetElementType().IsInterface;
}
}
公共类AnimalManager
{
私人只读IAnimal[]\u动物;
公共动物管理员(IAnimal[]动物)
{
_动物
}
}    
//在某处安装容器
公共IWindsorContainer ConfigureContainer()
{
IWindsorContainer=new WindsorContainer().Register(AllTypes.FromAssemblyContainer());
container.Kernel.Resolver.AddSubResolver(typeof(ArrayResolver));
IAnimalManager=container.Resolve();
}
容器现在将所有动物类型注入AnimalManager类中供您使用


科林G

ArrayResolver现在来了included@mausch我不知道干杯谢谢你花时间回答科林谢谢!更高兴的是知道现在更容易了ArrayResolver是Include
        var container = new WindsorContainer();

        container.AddComponent("Dog", typeof(IMakeNoise), typeof(Dog));
        container.AddComponent("Cat", typeof(IMakeNoise), typeof(Cat));
        container.AddComponent(
            "AnimalManager", typeof(AnimalManager), typeof(AnimalManager)
            );

        IList<IMakeNoise> noisemakers = new List<IMakeNoise> {new Dog(), new Cat()};

        var manager = container.Resolve<AnimalManager>(
            new Hashtable { { "noisemakers", noisemakers } }
            );

        manager.PokeAnimals();
        container.Release(manager);
class Program
{
    static void Main(string[] args)
    {
        var container = new WindsorContainer();
        container.Register(AllTypes.Pick().FromAssembly(Assembly.GetExecutingAssembly()).AllowMultipleMatches());

        var dog = container.Resolve<Dog>();
        var animals = container.ResolveAll<IAnimal>();
    }
}

public interface IAnimal
{
}

public class Dog : IAnimal
{
}

public class Cat : IAnimal
{
}

public class Fish : IAnimal
{
}
public class ArrayResolver : ISubDependencyResolver
{
    private readonly IKernel kernel;

    public ArrayResolver(IKernel kernel)
    {
          this.kernel = kernel;
    }

    public object Resolve(CreationContext context, ISubDependencyResolver parentResolver,
                          ComponentModel model,
                          DependencyModel dependency)
    {
         return kernel.ResolveAll(dependency.TargetType.GetElementType(), null);
    }

    public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver,
                          ComponentModel model,
                          DependencyModel dependency)
    {
          return dependency.TargetType != null &&
        dependency.TargetType.IsArray &&
        dependency.TargetType.GetElementType().IsInterface;
    }
}

public class AnimalManager
{
     private readonly IAnimal[] _animals;
     public AnimalManager(IAnimal[] animals)
     {
         _animals = animals
     }
}    

//Setup container somewhere
public IWindsorContainer ConfigureContainer()
{
     IWindsorContainer container = new WindsorContainer().Register(AllTypes.FromAssemblyContaining<Cat>());
     container.Kernel.Resolver.AddSubResolver(typeof(ArrayResolver));

     IAnimalManager manager = container.Resolve<AnimalManager>();
}