2016-02-05 128 views
0

仍然在探索新的ASP.NET MVC5,现在使用DI构建!ASP.Net MVC 6:递归依赖注入

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

// 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”工作得很好。

此外,控制器中的注入也起作用。 但现在我的塌陷:我分隔的数据访问我从处理程序,并很明显,我想将它们注入,以及:

public class UserEndPointConfigurationHandler 
{ 
    private readonly DataAccess.UserEndPointAccess _access; 

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

但是BAM,UserEndPointAccess不能得到解决。所以,即使我直接向一个无参数构造函数的DI请求,我也需要注册它。对于这种情况,当然我应该Interface和注册它们,但是对于我也注入的内部帮助类,这意味着什么?

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

微软DI的方法与完美的Unity是否完全不同,在那里我可以像我想要的那样精细地分离出来?

在此先感谢。

马蒂亚斯

编辑@Nightowl:我这里补充我的答案,因为它是一个长一点。 首先,Unity会自动创建实例,如果我请求混凝土类型。这允许我注入类型I注册和类型,像帮助者类等,我不需要。这种组合使我可以在任何地方使用DI。

另外在你的例子中,我需要知道WebGui中的DataAcces,这非常紧密。那么,我知道有通过Reflection的解决方案,但是我希望微软在这个主题上做了些什么,但是这可能意味着一个变化。

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

也许我只是被宠坏了,DI-图书馆做了些什么,可能他们也做得很多,但根据我的信息,目前微软的实施只是一个巨大的降级。

回答

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中也是如此。