C# Microsoft.Extension.Dependencyinjection问题

C# Microsoft.Extension.Dependencyinjection问题,c#,dependency-injection,asp.net-core,asp.net-core-mvc,C#,Dependency Injection,Asp.net Core,Asp.net Core Mvc,我正在用asp net core 1.1制作一个RESTfull API,这是我第一次使用net core,我感到相当困惑 我需要从我的应用程序中访问neo4j数据库,但我只需要设置一次到数据库的连接,这样对于每个请求,我就不必重新连接到数据库。因此,我创建了一个处理建立连接的类,然后有一个newSession()方法,它将非常明显地返回一个新的ISession实例,我可以用它查询数据库 这是我目前拥有的代码: namespace DependencyInjection.Interfaces {

我正在用asp net core 1.1制作一个RESTfull API,这是我第一次使用net core,我感到相当困惑

我需要从我的应用程序中访问neo4j数据库,但我只需要设置一次到数据库的连接,这样对于每个请求,我就不必重新连接到数据库。因此,我创建了一个处理建立连接的类,然后有一个newSession()方法,它将非常明显地返回一个新的ISession实例,我可以用它查询数据库

这是我目前拥有的代码:

namespace DependencyInjection.Interfaces
{
    public interface IDatabaseSessionRepository
    {
        IDriver Driver { get; set; }

        void IDatabaseSessionRepository();

        ISession newSession();
    }

    public interface IDatabaseRepository
    {
        ISession Session { get; set; }

        void IDatabaseRepository();
    }
}

我希望有一个DatabaseSessionRepository实例,并能够在DatabaseRepository类中访问该实例,以便获得ISession实例

我的想法是,我可以在DatabaseSessionRepository上使用services.AddSingleton(),但是如何在DatabaseRepository类中仅实例化一次并能够访问它呢


我还将为DatabaseRepository使用services.AddScoped()生存期,您也知道。

这不是更容易吗

services.AddSingleton<IDriver>(p => GraphDatabase.Driver("bolt://localhost:8797", AuthTokens.Basic("neo4j", "neo4j"));
services.AddScoped<ISession>(p => p.GetService<IDriver>().Session());
当然,在DI容器中注册的任何其他类中:

// inside ConfigureServices:    
services.AddScoped<IDatabaseRepository, DatabaseRepository>();

// your class:
public class DatabaseRepository : IDatabaseRepository
{
    public ISession Session { get; set; }

    public DatabaseRepository(ISession session)
    {
        Session = session;
    }

    //other methods here
}
//内部配置服务:
services.addScope();
//你们班:
公共类数据库存储库:IDatabaseRepository
{
公共ISession会话{get;set;}
公共数据库存储库(ISession会话)
{
会话=会话;
}
//这里还有其他方法
}

为什么不使用构造函数注入?我不确定Microsoft在.NET标准中提出的DI系统是否支持基于属性的注入。@casperOne他可以将AutoFAC设置为属性的DI提供程序。但建议使用构造函数注入。因此,只要在构造函数中引用一个接口,无论在何处使用它,都会得到一个实例。@FilipCordas你是说我应该只使用服务。AddSingleton()在IDatabaseSessionRepository上。然后,当我在IDatabaseRepository的构造函数中引用它时,它将始终自动使用同一个实例?@ajanimember我不是说它应该是一个由您决定的单例。但是,如果注册单个实例,则每个应用程序只会创建一个对象。请记住,ASP.NET Core中使用的
Microsoft.Extensions.DependencyInject
不是特定于.NET Core的。我不建议这样做,因为
ISession
IDisposable
更好地创建一个应用程序
services.AddSingleton(p=>()=>p.GetService().Session())
因此您可以控制会话何时被释放。@FilipCord在其作用域结束后(在本例中是在ASP.NET核心请求完成后)作为DI容器。注册工厂方法根本不是必需的。@FedericoDipuma True,但即使您根本不使用会话,也会发生这种情况,因此它只会毫无理由地占用时间。如果您只在操作级别与[FromServices]一起使用它,则可以而不是在构造函数中。@FilipCordas为什么要在不使用依赖项的类中注入依赖项?您的用例非常有限,如果多次调用factory方法,还将导致在同一HTTP请求中创建多个
ISession
实例。在我看来,这比允许每个请求都有一个
ISession
问题要严重得多。任何现代DI框架(.NET Core包括在内)都通过使用作用域生存期来解决这个问题。
public class MyController : Controller
{
    private readonly ISession _session;
    public MyController(ISession session)
    {
        _session = session;
    }
}
// inside ConfigureServices:    
services.AddScoped<IDatabaseRepository, DatabaseRepository>();

// your class:
public class DatabaseRepository : IDatabaseRepository
{
    public ISession Session { get; set; }

    public DatabaseRepository(ISession session)
    {
        Session = session;
    }

    //other methods here
}