在解析公共类的同时注入内部帮助类 [英] Injecting an internal helper class while resolving a public class

查看:20
本文介绍了在解析公共类的同时注入内部帮助类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下架构,其中引用内部 Helper 类的公共 Service 类存在于另一个程序集中:

ApplicationAssembly {公共类小部件{公共小部件(ReferencedAssembly.Service 服务){ ... }}}引用程序集 {公共类服务{公共服务(Helper helper) { ... }}类助手 { ... }}

(我意识到我不能将内部类放入公共类的构造函数的参数中——我只是想说明我所追求的 IoC 模式.)

问题是ApplicationAssembly 看不到ReferencedAssembly.Helper,所以它不能在我的IoC 容器(在这种情况下是Autofac)中注册.结果,当我尝试解析 Service 时,无法解析 Helper.我最好的选择是什么?

  • 选项 1:从 Service 的构造函数中删除 Helper 并在构造函数中显式地将其更新.我不喜欢这个选项,因为它打破了 IoC 范式.

  • 选项 2:让 Helper 实现一个公共的 IHelper 接口,然后在注册 ReferencedAssembly 中添加一个公共模块Helper 作为 IHelper.我不喜欢这个选项,因为它需要 ApplicationAssembly 知道太多关于 Service 的实现细节,如果用户忘记在启动时注册该模块,一切都会中断.p>

  • 选项 3:在 Service 上创建一个公共静态构造函数,专门为 ReferencedAssembly 构建第二个 IoC 容器并在其中注册 Helper它.从 Service 的构造函数中移除 Helper 并使用第二个 IoC 容器在构造函数中解析它.这似乎是我最好的选择,但需要比其他人更多的管道"代码.我也不喜欢公共静态构造函数.

  • 选项 4. 完全改变我的架构.

解决方案

向 Autofac 注册内部类型的方法是包含一个 Autofac Module 内部类型的程序集,并将模块注册到容器中.因为模块在同一个程序集中,它可以使用内部类型配置 ContainerBuilder.

我认为最好的选择是让 Service 实现一个公共接口,然后创建你当前内部的 Service 类.Autofac 很乐意实例化一个内部类来提供一个公共接口.

另一种选择(允许 Service 对内部类型进行构造函数依赖)是将 Service 的构造函数设为内部,然后使用构造函数查找器Service 类型注册:

builder.RegisterType().FindConstructorsWith(new BindingFlagsConstructorFinder(BindingFlags.NonPublic));

I have the following architecture where a public Service class referencing an internal Helper class exists in another assembly:

ApplicationAssembly {
  public class Widget {
    public Widget(ReferencedAssembly.Service service) { ... }
  }
}

ReferencedAssembly {
  public class Service {
    public Service(Helper helper) { ... }
  }
  class Helper { ... }
}

(I realize that I can't put an internal class in the arguments of a public class's constructor--I'm just trying to illustrate the IoC pattern I'm going after.)

The problem is that ApplicationAssembly can't see ReferencedAssembly.Helper, so it can't be registered in my IoC container (Autofac in this case). As a result, Helper cannot be resolved when I try to resolve Service. What is my best option here?

  • Option 1: Remove Helper from Service's constructor and new it up in the constructor explicitly. I don't like this option because it kind of breaks the IoC paradigm.

  • Option 2: Make Helper implement a public IHelper interface, then add a public module within ReferencedAssembly that registers Helper as an IHelper. I don't like this option because it requires ApplicationAssembly to know too many implementation details about Service, and if the user forgets to register that module at startup everything breaks.

  • Option 3: Create a public static constructor on Service that builds a 2nd IoC container specifically for ReferencedAssembly and registers Helper in it. Remove Helper from Service's constructor and resolve it within the constructor using the 2nd IoC container. This seems like my best option but requires more "plumbing" code than the others. I'm also not a big fan of public static constructors.

  • Option 4. Change my architecture to something else altogether.

解决方案

The way to register internal types with Autofac is to include an Autofac Module inside the assembly with the internal types, and register the module with the container. Because the module is in the same assembly it can configure the ContainerBuilder with the internal types.

I think the best option is to make Service implement a public interface, then make the Service class that you have currently internal. Autofac will happily instantiate an internal class to provide a public interface.

The other option (to allow Service to take a constructor dependency on an internal type) is to make Service's constructor internal, and then use a constructor finder in the Service type registration:

builder.RegisterType<Service>()
  .FindConstructorsWith(new BindingFlagsConstructorFinder(BindingFlags.NonPublic));

这篇关于在解析公共类的同时注入内部帮助类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆