Autofac Collection命名和非命名类型

时间:2014-06-05 10:44:09

标签: autofac

我正在使用autofac并且需要解决大量规则,它们会被传递到特定的验证器,这些验证器使用一些通用规则和一些特定的规则。 Ninject有一个.WhenInjectedInto属性,我知道.Named<T>("")给了我类似的功能..但是

给出以下代码:

是否可以使用Foo和FooBar填充IFooValidator的规则。
而且,Barar和FooBar填充了IBarValidator的规则?

我有以下代码:

public static class Dependencies
    {
        public static IContainer Configure()
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<Foo>().As<IRule>();
            builder.RegisterType<Bar>().As<IRule>();

            builder.RegisterType<FooBar>().As<IRule>();

            builder.RegisterType<Foos>().As<IFooValidator>();
            builder.RegisterType<Bars>().As<IBarValidator>();

            return builder.Build();
        }
    }

    public interface IRule
    {
        string Name { get; }
    }

    public class Foo : IRule
    {
        public string Name { get { return "Foo"; }}
    }

    public class Bar : IRule
    {
        public string Name { get { return "Bar"; } }
    }

    public class FooBar : IRule
    {
        public string Name { get { return "FooBar"; } }
    }

    public interface IFooValidator
    {
        IList<IRule> Rules { get; set; }
    }

    public interface IBarValidator
    {
        IList<IRule> Rules { get; set; }
    }

    public class Foos : IFooValidator
    {
        public IList<IRule> Rules { get; set; }

        public Foos(IList<IRule> foo)
        {
            Rules = foo;
        }
    }

    public class Bars : IBarValidator
    {
        public IList<IRule> Rules { get; set; }

        public Bars(IList<IRule> bars)
        {
            Rules = bars;
        }
    }

我知道可以使用:

完成
builder.Register<IFooValidator>(context =>
            {
                var foos = context.ResolveNamed<IList<IRule>>("Foo");
                var foobar = context.Resolve<IList<IRule>>();

                return new Foos(foos.Concat(foobar).ToList());

            });

但感觉很乱,还有另一种方式吗?

1 个答案:

答案 0 :(得分:1)

我已经确定:

            builder.RegisterType<Foo>().Named<IRule>("Foo");
            builder.RegisterType<Bar>().Named<IRule>("Bar");

            builder.RegisterType<FooBar>()
                .As<IRule>()
                .Named<IRule>("Foo")
                .Named<IRule>("Bar");

            builder.RegisterType<Foos>().As<IFooValidator>().WithParameter((info, context) => info.Name == "foo", (info, context) => context.ResolveNamed<IList<IRule>>("Foo"));

如果有人能提供更好的答案,请做,我会很乐意给它做标记。

<强>更新

在对问题进行更多思考之后,注入这样的依赖关系并没有多大意义。因为改变无论如何都需要重建。我决定重构应用程序的这一部分以使用组合和继承而不是聚合和DI