【问题标题】:ASP.Net MVC 6: Recursive Dependency InjectionASP.Net MVC 6:递归依赖注入
【发布时间】:2016-02-05 09:49:42
【问题描述】:

仍在探索新的 ASP.NET MVC5,现在内置 DI!

到目前为止没问题,我可以只注入我的处理程序(我不喜欢术语服务,因为它为我定义了一个平台中立接口):

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry(Configuration);

        services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));

        services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
        services.AddSingleton(typeof(Logic.NetworkHandler));

        services.AddMvc();
    }

工作正常,强类型配置对象“AppSettings”也工作正常。

控制器中的注入也可以工作。 但现在我崩溃了:我将 DataAccess 与 Handler 分开,显然我也想注入它们:

public class UserEndPointConfigurationHandler
{
    private readonly DataAccess.UserEndPointAccess _access;

    public UserEndPointConfigurationHandler(DataAccess.UserEndPointAccess access)
    {
        _access = access;
    }

但是 bam,UserEndPointAccess 无法解析。所以看起来即使我直接向 DI 请求一个带有无参数构造函数的类,我也需要注册它。对于这种情况,当然我应该接口并注册它们,但这对于我也注入的内部帮助类意味着什么?

根据文档:http://docs.asp.net/en/latest/fundamentals/dependency-injection.html#recommendations 以及我发现的示例,世界上所有人似乎只在控制器和一些存储库之间进行通信。程序集中没有业务层和不同抽象级别的类。

Microsoft DI 方法是否与优秀的 Unity 方法完全不同,我可以在其中真正解耦,尽可能细粒度?

提前致谢。

马蒂亚斯

编辑@Nightowl:我在这里添加我的答案,因为它有点长。 首先,如果我请求具体类型,Unity 会自动创建实例。这允许我注入我注册的类型和类型,如 Helper 类等。我不需要。这种组合让我可以在任何地方使用 DI。

在您的示例中,我还需要知道 WebGui 中的 DataAcces,这是非常紧密的耦合。好吧,我知道通过 Reflection 可以解决这个问题,但我希望微软在这个主题中做点什么,但这可能意味着很大的改变。

还允许 Unity 存储实例或说明如何创建它们,这是目前缺少的另一个巨大功能。

可能我只是被宠坏了,精炼的 DI 库所做的事情,可能他们也做了很多,但根据我的信息,目前 Microsoft 实现只是一个巨大的降级。

【问题讨论】:

    标签: asp.net asp.net-mvc dependency-injection asp.net-core-mvc


    【解决方案1】:

    MVC Core 遵循composition root 模式,其中对象图 是根据一组指令来实例化它们的。我认为您误解了 IServiceCollection 的用途。它不存储实例,它存储有关如何创建实例的说明。直到对象图中某处的构造函数请求一个作为构造函数参数时,才会真正创建实例。

    因此,简而言之,您的服务(您称之为UserEndPointAccess)在您请求时没有被实例化的原因是您没有配置IServiceCollection 并提供有关如何创建它的说明。

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry(Configuration);
    
        services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));
    
        services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
        services.AddSingleton(typeof(Logic.NetworkHandler));
    
        // Need a way to instantiate UserEndPointAccess via DI.
        services.AddSingleton(typeof(DataAccess.UserEndPointAccess));
    
        services.AddMvc();
    }
    

    所以看起来即使我直接向 DI 请求一个带有无参数构造函数的类,我也需要注册它。

    如果您正确执行 DI,每个服务类将只有一个构造函数。如果您有多个,则称为bastard injection anti-pattern,这实质上意味着您通过添加对其他类的引用作为外部默认值,将您的类定义与其他类紧密耦合。

    是的,您需要注册所需的每种类型(这不是 MVC 的默认注册的一部分)。在 Unity 中也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多