Castle Windsor按对象约定安装多个实例服务

时间:2014-11-25 20:27:49

标签: castle-windsor

在做了一些阅读之后,似乎将原始数据类型传递给构造函数并不是处理构造函数注入的最佳方法(不确定这是否属实,但是可以购买它)。 因此需要用户提供一些信息(在命令提示符下输入)我正在执行以下操作。

注意:只是一个例子,但在概念上是相同的

public interface IArg
{
    string Value{get;set;}
}

public interface IServerNameArg : IArg{}

public class ServerName : IServerNameArg
{
    public string Value{get;set;}
}

public interface ISomethingElseArg:IArg{}

public class SomethingElseArg : ISomethingElseArg
{
    public string Value{get;set;}
}


public interface ICommandArgs
{
    IServerNameArg{get;set;}
    ISomethingElseArg{get;set;]
}

因此,对于之前的项目,我做了类似的事情,但没有为每个设置设置接口,只是在需要这些设置的地方传递整个对象。 并不可怕,但我可以看到只想传递相关论点的一些价值。

container.Register(Componenet
    .For<IArgs>()
    .Instance(args)

所以我的第一个问题(如果我正确地处理这个问题)是否可以执行类似的.Instance安装使用约定并拥有我的ICommandArgs的每个属性并安装为实例服务? 不确定它会是什么样子但是像

container.Register(Classes
    .From(typeof(ICommandArgs))
    .BasedOn<IArg>()
    .WithServiceBase());

我知道我可以单独安装每个属性,但我希望将来能够添加args并让他们连接起来,而不必记得安装它们。 我正在修改的另一种方法是使用linq和reflection从我的ICommandArgs实例中获取IArg类型的所有属性,然后将每个属性作为实例安装。

我走得太远了吗? 我应该依赖ICommandArgs并在那里安装实例服务吗?

提前致谢

1 个答案:

答案 0 :(得分:0)

如此反思。使用下面的代码,我将从&#34; args&#34;

的实例中提取所有属性
        //get all properties from args class that implement IVar so they can be registered automatically  
        var argsToRegister = _args.GetType().GetProperties()
                .Where(x =>
                    x.GetValue(_args) != null
                    && x.PropertyType.GetInterfaces().Contains(typeof(IVar)))
                .Select(x => new
                {
                    x.Name,
                    Type = x.PropertyType,
                    Value = x.GetValue(_args)
                }).ToList();

然后我将每个接口注册为所有接口的实例(这是我的解决方案特有的,你应该注意你注册的内容)

        //register each IVar from the args instance as instance vars
        foreach (var arg in argsToRegister)
        {
            var types = arg.Type.GetInterfaces().ToList();
            types.Add(arg.Type);

            container.Register(Component
                .For(types)
                .Instance(arg.Value)
                .IsDefault()
               );
        }

然后我去注册所有尚未注册的其他IVars

        //register all IVar that are not contained as properties in the args implementation 
        container.Register(Classes
            .FromThisAssembly()
            .BasedOn<IVar>()
            .If(t=> !argsToRegister.Any(a=>a.Type.IsAssignableFrom(t)))
            .WithServiceBase()
        );