有没有办法插入autofac的实例化过程?

时间:2016-09-19 08:17:08

标签: c# filter autofac instantiation

我有三个类声明,如上面的

 [Plug("hello")]
 public class Plug1 : IPlug{}
 [Plug("hello")]
 public class Plug2 : IPlug{}
 [Plug("world")]
 public class Plug3 : IPlug{}

当我使用container.Resolve<IEnumerable<IPlug>>()解析时,我得到了实现IPlug接口的所有实例,但是,我希望得到第一个和第二个(或者世界,实例被标记为属性Plug("hello"))。

有没有办法实现它?

我想避免使用

container.Resolve<IEnumerable<IPlug>>()
         .Where(t => t.FirstAttribute<Plug>() != null 
                     && t.FirstAttribute<Plug>().Id == "Hello")

我一直认为这不是表演的最佳实践。

1 个答案:

答案 0 :(得分:1)

有很多方法可以做你想要的。

最简单的方法是将您的类型注册为命名注册

builder.RegisterType<Plug1>().As<IPlug>().WithMetadata("plug", "hello");
builder.RegisterType<Plug2>().As<IPlug>().WithMetadata("plug", "hello");
builder.RegisterType<Plug3>().As<IPlug>().WithMetadata("plug", "world");

您还可以使用该属性注册这些类型:

builder.RegisterType<Plug1>()
       .As<IPlug>()
       .WithMetadata("plug", typeof(Plug1).FirstAttribute<Plug>().?Id ?? "Default");

然后,您将能够使用IPlug进行所有已命名的IEnumerable<Meta<IPlug>>注册:

container.Resolve<IEnumerable<Meta<IPlug>>>()
         .Where(m => m.Metadata["plug"] as String == "hello")
         .Select(m => m.Value);

如果您不想在运行时进行过滤,但在IoC根组合期间,IEnumerable<IPlug>将始终解析已过滤的IEnumerable<IPlug>,那么您可以覆盖IEnumerable<IPlug>注册:

builder.Register(c => c.Resolve<IEnumerable<Meta<IPlug>>>()
                       .Where(m => m.Metadata["plug"] as String ==  "hello")
                       .Select(m => m.Value))
       .As<IEnumerable<IPlug>>();