Autofac注册并使用名称解析

时间:2016-03-13 20:46:42

标签: c# dependency-injection autofac

我正在尝试按名称注册对象,然后在注册期间将它们作为参数传入另一种类型的ctor。

希望我的例子足够清楚,这里是:

public class Obj : IObj
{
    public class Obj(string name)
}

I register the following objects like this :


public void RegisterMyObj(string name)
{
    // Keyed with the object name
    builder.Register<Obj>().Named<IObj>(name).WithParameter(name).SingleInstance();
}

public class ObjectsHolder : IObjectsHolder
{
    public ObjectsHolder (List<IObj> objsToHold))
}

// I want to register my ObjectsHolder in the following way:
for example, this is how I want to call it from my code: 
    RegisterObjectsHolder(string Obj1Name, string Obj2Name)

public void RegisterObjectsHolder(params string[] objectsNames)
{
    builder.Register<IObjectsHolder>().WithParameters(// Here comes the magic code which I can't figure out. 
                                                      // I want objects holder to be registered with the Obj instances whose names were passed to this method, 
                                                      // is there a way to do this?)
                                                      )
}   

我对注册的方式并不严格。如果你知道使用不同方法实现这一目标的方法,那也可以。

提前致谢!

2 个答案:

答案 0 :(得分:12)

您可能希望使用&#34; keyed&#34;而不是将您的服务注册为&#34;命名为&#34;服务。无法通过名称指定服务。但是您可以使用IIndex<TKey, TService>来检索具有指定类型的键控服务的类字典对象。所以你可以注册:

builder.RegisterType<Service1>().Keyed<IService>("key1");
builder.RegisterType<Service2>().Keyed<IService>("key2");
builder.RegisterType<Service3>().Keyed<IService>("key3");
builder.RegisterType<Service4>().Keyed<IService>("key4");
builder.RegisterType<Service5>().Keyed<IService>("key5");

稍后,在您的构造函数中,您可以注入:

public Test(IIndex<string, IService> serviceDictionary)
{
    var service1 = serviceDictionary["key1"];
}

我使用string个对象作为键,但您可以引用枚举并将其用作关键。

编辑:

如果您想缩小某些课程的可用服务范围,可以参考,例如引入不同的枚举类型作为键。

enum ServicesA { A1, A2, A3 }
enum ServicesB { B1, B2 }

然后,registratrions:

builder.RegisterType<Service1>().Keyed<IService>(ServicesA.A1);
builder.RegisterType<Service2>().Keyed<IService>(ServicesA.A2);
builder.RegisterType<Service3>().Keyed<IService>(ServicesA.A3);
builder.RegisterType<Service4>().Keyed<IService>(ServicesB.B1);
builder.RegisterType<Service5>().Keyed<IService>(ServicesA.B2);

现在,如果你注入IIndex<SerivcesA, IService>,只有Service1Service2Service3可用,IIndex<SerivcesB, IService>它将是Service4Service5

如果您从上面加入两个注册

,您可以链接Keyed注册
builder.RegisterType<Service1>().Keyed<IService>(ServicesA.A1).Keyed<IService>("key1");` 

等,您可以同时使用IIndex<YourEnum, IService>只使用IService个实施,或IIndex<string, IService>同时使用static bool Login(SignupData sd) { bool success=false; /* Perform login-related actions here */ }

答案 1 :(得分:0)

我喜欢通过命名约定注册。

 var assembly = Assembly.GetExecutingAssembly();
 builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();

然后将依赖项放在构造函数中。

 private IUserService UserService { get; set; }
    public UserController(IUserService userService)
    {
        UserService = userService;
    }

这样我只需坚持我的命名约定即可完成工作。在项目初始设置之后,老实说,我很少需要再次查看autofac。