C# 一些castle组件的运行时设置很困难
我的问题(我认为)可以简单地用这个问题来描述: 如何让“管理器”类拥有一个特定接口的所有可能的具体实现的列表,该接口已注册为注入到其中的组件,以便可以对其进行迭代?(由于恼人的体系结构原因,我无法使用app.config注册我的组件,所以我猜只有运行时注册) 编辑: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配
啊哈!-发现我可以使用以下方式传入自己的配置文件:
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类中供您使用
科林GArrayResolver现在来了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>();
}