C# 使用Autofac实现N层体系结构时获取空参数

C# 使用Autofac实现N层体系结构时获取空参数,c#,asp.net-web-api,dependency-injection,autofac,C#,Asp.net Web Api,Dependency Injection,Autofac,我创建了这个简单的WebAPI项目,其中包含以下库类 协调(服务层) 域(业务层) 数据(数据层) DTO(用于webapi的DTO) 基本上WebAPI项目调用(参考)DTO和协调。协调调用域和域调用数据 这就是我的结构 我的问题是使用Autofac实现依赖项注入。我可以调用协调层,当我试图调用域层时,这就是它感到困惑的地方 这就是我定义registertype的方式 public class AutofacWebapiConfig { public stati

我创建了这个简单的WebAPI项目,其中包含以下库类

  • 协调(服务层)
  • 域(业务层)
  • 数据(数据层)
  • DTO(用于webapi的DTO)
基本上WebAPI项目调用(参考)DTO和协调。协调调用域和域调用数据

这就是我的结构

我的问题是使用Autofac实现依赖项注入。我可以调用协调层,当我试图调用域层时,这就是它感到困惑的地方

这就是我定义registertype的方式

public class AutofacWebapiConfig
    {

        public static IContainer Container;

        public static void Initialize(HttpConfiguration config)
        {
            Initialize(config, RegisterServices(new ContainerBuilder()));
        }

        public static void Initialize(HttpConfiguration config, IContainer container)
        {
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }

        private static IContainer RegisterServices(ContainerBuilder builder)
        {
            //Register your Web API controllers.  
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            builder.RegisterAssemblyTypes(Assembly.Load(nameof(Coordination)))
              .Where(t => t.Namespace.Contains("Services"))
              .As(t => t.GetInterfaces().FirstOrDefault(i => i.Name == "I" + t.Name));

            builder.RegisterAssemblyTypes(Assembly.Load(nameof(Domain)))
              .Where(j => j.Namespace.Contains("Domain"))
              .As(j => j.GetInterfaces().FirstOrDefault(i => i.Name == "I" + j.Name));

            //Set the dependency resolver to be Autofac.  
            Container = builder.Build();

            return Container;
        }

    }
  • 出现了一些问题。首先,它不知道如何找到域,因为理论上WebAPI不与域层对话
  • 我确实添加了它作为引用,但现在我得到了一个空参数错误。ServiceType不能为null
  • 在服务实现过程中,没有任何东西从我身上跳出来

     public class StudentService : IStudentService
        {
            private readonly IStudentDomain studentDomain;
            public StudentService(IStudentDomain _studentDomain)
            {
                this.studentDomain = _studentDomain;
            }
    
            public async Task<StudentDto> GetStudentByID(string id)
            {
                var test = this.studentDomain.getStudentByID(id);
            }
    }
    
        public class StudentDomain : IStudentDomain
        {
    
            public StudentDomain()
            {
    
            }
    
            /// <summary>
            /// Return student
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            StudentEntity IStudentDomain.getStudentByID(string id)
            {
                StudentEntity student = new StudentEntity("dd", "aa", "ddd");
                return student;
            }
        }
    

    注册
    Domain
    似乎有问题,因为
    StudentEntity
    没有相应的接口和
    。As(j=>j.GetInterfaces().FirstOrDefault(i=>i.Name==“i”+j.Name))
    将无法为其找到一个接口

    如果不想手动添加具有接口的所有类型,请尝试以下操作:

    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain"))
              .AsImplementedInterfaces()
    
    您可能希望/需要区分有接口和无接口的类型,您可以尝试下一种方法:

    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain") && j.GetInterfaces().Any())
              .AsImplementedInterfaces()
    
    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain") && !j.GetInterfaces().Any())
              .AsSelf();
    
    附言


    此外,我还建议将所有
    Assembly.Load(nameof(SOME_NAME))
    更改为
    typeof(TYPE_NAME).Assembly
    ,我认为它更具可读性和明显性。

    注册
    域似乎存在问题,因为
    StudentEntity
    没有相应的接口和
    (j=>j.GetInterfaces().FirstOrDefault(i=>i.Name==“i”+j.Name))
    将无法为其找到一个

    如果不想手动添加具有接口的所有类型,请尝试以下操作:

    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain"))
              .AsImplementedInterfaces()
    
    您可能希望/需要区分有接口和无接口的类型,您可以尝试下一种方法:

    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain") && j.GetInterfaces().Any())
              .AsImplementedInterfaces()
    
    builder.RegisterAssemblyTypes(typeof(StudentDomain).Assembly)
              .Where(j => j.Namespace.Contains("Domain") && !j.GetInterfaces().Any())
              .AsSelf();
    
    附言


    另外,我建议将所有
    Assembly.Load(nameof(SOME_NAME))
    更改为
    typeof(TYPE_NAME).Assembly
    ,我认为它更具可读性和明显性。

    请在您的问题中添加完整的异常详细信息(包括异常的堆栈跟踪和所有内部异常)。(无屏幕截图,仅文本)目前,任何人都无法回答您的问题,因为失败的原因不太可能在您提供的代码中。必须创建更多的上下文。您的问题也像是“如何调试代码”这是一种不适合堆栈溢出的问题。尝试在一个新的小项目中重现该问题也很好。从一个空项目开始,逐步添加代码,直到发现该问题。然后返回,直到找到异常的原因。我知道如果删除builder.Regist,我可以让它工作EraseMblyTypes(Assembly.Load(nameof(Domain))),但此时我无法实现我的业务层。我认为问题是由于加载第一个OrDefault调用返回null的类型造成的。根据您的评论,我确实将第二个builder.reg…行更改为此builder.RegisterType().As();这是可行的。但是我不想单独定义我的域层中的所有接口如何搜索所有接口请在问题中添加完整的异常详细信息(包括异常的堆栈跟踪和所有内部异常)。(没有屏幕截图,只有文本)目前,任何人都无法回答您的问题,因为失败的原因不太可能在您提供的代码中。必须创建更多的上下文。您的问题也像是“如何调试代码”这是一种不适合堆栈溢出的问题。尝试在一个新的小项目中重现该问题也很好。从一个空项目开始,逐步添加代码,直到发现该问题。然后返回,直到找到异常的原因。我知道如果删除builder.Regist,我可以让它工作EraseMblyTypes(Assembly.Load(nameof(Domain))),但此时我无法实现我的业务层。我认为问题是由于加载第一个OrDefault调用返回null的类型造成的。根据您的评论,我确实将第二个builder.reg…行更改为此builder.RegisterType().As();这是可行的。但是,我不想单独定义我的域层中的所有接口。当我将load(nameof(type_name))更改为typeof(type_name)时,如何搜索所有接口。程序集我收到以下错误:域是名称空间,但与类型一样使用。抱歉,请使用
    typeof(StudentDomain)
    或相应程序集中的任何其他类型。当我将load(nameof(type\u name))更改为typeof(type\u name)时,程序集中出现以下错误:域是名称空间,但与类型类似。抱歉,请在相应程序集中使用
    typeof(StudentDomain)
    或任何其他类型。