按照惯例,自动装配 - 与funq servicestack(servicestack with f

2019-09-01 04:15发布

我有一个服务,它需要一个IMyDependency在其构造。 IMyDependency,MyDependency和服务都住在同一个组件。 MyDependency有一个单一的,公共,无参数构造函数。

令我惊讶的是,这并不工作:

container.RegisterAutoWired<IMyDependency>();

它抛出一个“System.NullReferenceException”。

它的工作原理,如果我这样做:

container.RegisterAutoWiredAs<MyDependency, IMyDependency>();

不过,这样做的:

container.RegisterAs<MyDependency, IMyDependency>();

那么区别是什么呢? 如果“自动布线”无法找到具体的实现,而且它没有什么区别是否需要依赖的服务就可以解决,那么什么是自动布线?

被Funq应该能够通过约定来找到你的具体实现? 如果是这样,那是什么惯例,如果没有同名的烦躁?

谢谢。

Answer 1:

对于这样的简单查询,最好只接触源,比如这里是源代码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。



Answer 2:

你的意思是“我怎样才能实现一个解决方案,通过组件进行搜索,并根据公约的ServiceStack IOC自动注册类?”

如果是的话,我会为你提供一个解决方案:

  1. 创建你的注入,能够类将实现一个接口。
  2. 有你的注入,能够类实现该接口。
  3. 在引导捆扎代码使用反射来搜索您的组件,并得到所有实施注射,能接口的类的列表。
  4. 使用反射来获取基于您约定的类名和接口。
  5. 调用ServiceStack IOC方法RegisterAutoWiredType并传入类和接口来注册它们。

例如,如果我们的命名规则是类名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();
    }
}


文章来源: servicestack with funq - autowiring by convention