6

我有一个在其构造函数中采用 IMyDependency 的服务。IMyDependency、MyDependency 和服务都存在于同一个程序集中。MyDependency 有一个单一的、公共的、无参数的构造函数。

令我惊讶的是,这不起作用:

container.RegisterAutoWired<IMyDependency>();

它抛出一个“System.NullReferenceException”。

如果我这样做,它会起作用:

container.RegisterAutoWiredAs<MyDependency, IMyDependency>();

但是,这样做也是如此:

container.RegisterAs<MyDependency, IMyDependency>();

那么区别是什么呢?如果“自动布线”找不到具体的实现,而需要依赖的服务能否解决也无济于事,那什么是自动布线?

Funq 是否应该能够按照惯例找到您的具体实现?如果是这样,该约定是什么,如果不是同名?

谢谢。

4

2 回答 2

8

您的意思是“我如何实现一个解决方案来搜索程序集并根据约定在 ServiceStack IOC 中自动注册类?”

如果是这样,我可能会为您提供解决方案:

  1. 创建一个您的可注入类将实现的接口。
  2. 让您的可注入类实现该接口。
  3. 在引导代码中,使用反射来搜索您的程序集并获取所有实现可注入接口的类的列表。
  4. 使用反射根据您的约定获取类名和接口。
  5. 调用ServiceStack IOC方法RegisterAutoWiredType并传入类和接口进行注册。

例如,如果我们的命名约定是 ClassName IClassName:

private static void RegisterCustomTypes(Container container)
{
  //Get the Assembly Where the injectable classes are located.
  var assembly = Assembly.GetAssembly(typeof(IInjectable));

  //Get the injectable classes 
  var types =assembly.GetTypes()
    .Where(m => m.IsClass && m.GetInterface("IInjectable") != null);

  //loop through the injectable classes
  foreach (var theType in types)
  {
    //set up the naming convention
    var className = theType.Name;
    var interfaceName = string.Concat("I", className);
    //create the interface based on the naming convention
    var theInterface = theType.GetInterface(interfaceName);
    //register the type with the convention
    container.RegisterAutoWiredType(theType, theInterface);
  }
}

public interface IInjectable
{

}

//This class can be injected
public interface ITestManager : IInjectable
{
    void Execute(int id);
}

public class TestManager : ITestManager
{
    public void Execute(int id)
    {
        throw new System.NotImplementedException();
    }
}
于 2013-10-15T13:52:24.413 回答
5

对于像这样的简单查询,最好只联系源,例如,这里是RegisterAutoWired的源代码:

public IRegistration<T> RegisterAutoWired<T>()
{
    var serviceFactory = GenerateAutoWireFn<T>();
    return this.Register(serviceFactory);
}

它在具体实现上生成一个自动连线工厂。接口没有实现,它需要是一个具体的类。

RegisterAs的源代码:

public IRegistration<TAs> RegisterAs<T, TAs>() where T : TAs 
{
    return this.RegisterAutoWiredAs<T, TAs>();
}

这只是您可以使用的较短别名,而不是 RegisterAutoWiredAs。

于 2013-04-26T01:03:38.550 回答