使用Autofac时将主应用程序与其他依赖项隔离

问题描述:

我正在使用Autofac,我想将主应用程序与我在Autofac容器中注册的所有依赖项隔离。使用Autofac时将主应用程序与其他依赖项隔离

这是一个可能的方案:

我有一个包含4个项目中的溶液。 ProjectA是主应用程序,它是一个C#控制台程序,包含我重命名为ClassA的常用静态类程序。 ProjectB只包含ClassB,而projectC包含ClassC。 ClassB和ClassC都位于它们的接口IClassB和IClassC后面,这些接口放置在projectD中。 ClassA通过IClassB调用ClassB的方法。 ClassB通过IClassC调用ClassC的方法。

的ClassA里面我建立Autofac容器并注册项目B和C的组件:

static class ClassA 
{ 
    static void Main() 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterType<ClassB>().As<IClassB>(); 
     builder.RegisterType<ClassC>().As<IClassC>(); 
     IContainer container = builder.Build(); 
    } 
} 

此时项目A具有的所有其他项目的引用,即使使用的app.config或者基于寄存器的依赖关系Autofac配置。

有没有什么办法可以让ProjectA只依赖放置接口的ProjectD,而不是依赖于所有项目?

+1

组合根必须知道所有类型。你不能没有 –

这是你可以分两个步骤做:

  1. 第一步将是具有在同一个地方的所有项目的依赖关系。 要为项目B,C,D执行此操作,请单击属性>构建>输出路径设置项目A的bin/debug目录。 现在,当您编译解决方案时,您应该在项目中看到A,B,C,D的dll A的bin/debug文件夹。

  2. 接下来,你需要把所有从组件您指定选择的依赖注入容器的注册它们的类型,在这种情况下Autofac,像这样:


    class ClassA 
    { 
     static void Main(string[] args) 
     { 
      // specify here the projects needed to resolve your types 
      var projects = new List<string> { "ProjectB", "ProjectC", "ProjectD" }; 
      var types = GetAllTypes(projects); 
      var interfaces = types.Where(t => t.IsInterface).ToList(); 

      // init autofac container builder 
      var builder = new ContainerBuilder(); 

      // add types to the builder 
      foreach (var interfaceType in interfaces) 
      { 
       var implementingType = types.FirstOrDefault(t => interfaceType.IsAssignableFrom(t) && !t.IsInterface); 

       if (implementingType != null) 
       { 
        builder.RegisterType(implementingType).As(interfaceType); 
       } 
      } 

      var container = builder.Build(); 

      // test ClassB and ClassC can be instantiated through their interface 
      using (var scope = container.BeginLifetimeScope()) 
      { 
       var classB = scope.Resolve<IClassB>(); 
       var classC = scope.Resolve<IClassC>(); 
      } 
     } 

     // get all the classes and interfaces from the selected projects 
     private static List<Type> GetAllTypes(List<string> projects) => 
      Directory.EnumerateFiles(AppDomain.CurrentDomain.BaseDirectory) 
       .Where(f => f.ToLower().EndsWith(".dll")) 
       .Where(f => projects.Any(a => Assembly.ReflectionOnlyLoadFrom(f).GetName().Name.StartsWith(a))) 
       .Select(a => Assembly.ReflectionOnlyLoadFrom(a).FullName) 
       .Select(Assembly.Load) 
       .SelectMany(a => a.GetTypes()) 
       .ToList(); 

    } 

注意 - 这方法假定您想要为每个接口注册一种类型。做其他事情需要更复杂的注册策略,但您可以随时添加。

+0

似乎是一种确实的方式。在我将您的答复标记为接受之前,我会再等一会儿,看看是否提出了其他替代方案。 –