在何处使用依赖注入注册上下文

Where to register the context with dependency injection

根据this教程我应该:

Register your context with dependency injection

教程描述了我应该找到方法 ConfigureServices() 并在其中输入建议的代码。

这是我的 startup.cs:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(MyProject.Startup))]
namespace MyProject
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

所以我不知道该把代码放在哪里。

由于项目不兼容.net core 2.1,需要将Project->属性改为.Net Framework 4.6.1 并安装软件包 Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.Tools

我尝试将依赖项注入添加到 global.asax.cs 文件中,如下所示:

protected void Application_Start()
        {
            var services = new ServiceCollection();
            ConfigureServices(services);
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
}

private void ConfigureServices(IServiceCollection services)
    {
        var connection = @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;ConnectRetryCount=0";
        services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));
    }

我成功完成了这一步并创建了控制器并且它可以工作,但是我没有选择正确的上下文 (BloggingContext),所以它创建了第二个数据库。所以,我需要用 BloggingContext 创建一个控制器,你知道怎么做吗?

显示的启动版本和教程相互冲突。

如果这是 Asp.Net 核心 MVC 应用程序,那么您可以自己添加该方法。 Startup class 是约定的一部分。

public partial class Startup {
    //...

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

引用App startup in ASP.NET Core

The ConfigureServices method

The ConfigureServices method is:

  • Optional.
  • Called by the host before the Configure method to configure the app's services.
  • Where configuration options are set by convention.

但是,如果您尝试在 Asp.Net MVC 5+ (这是 GitHub 项目的目标) 中使用 .Net Core 技术,那么您将需要修改您的方法以适应在非核心平台上使用 .Net Core 依赖注入。

首先,您需要一个 IDependencyResolver,它是那个版本的 Asp.Net MVC 使用的 DI 框架,以及一种用您自己的解析器替换默认解析器的方法。

public sealed class CoreDependencyResolver : System.Web.Mvc.IDependencyResolver {
    private readonly System.Web.Mvc.IDependencyResolver mvcInnerResolver;
    private readonly IServiceProvider serviceProvider;

    public CoreDependencyResolver(IServiceProvider serviceProvider, System.Web.Mvc.IDependencyResolver dependencyResolver) {
        this.serviceProvider = serviceProvider;
        mvcInnerResolver = dependencyResolver;
    }

    public object GetService(Type serviceType) {
        object result = this.serviceProvider.GetService(serviceType);
        if (result == null && mvcInnerResolver != null)
            result = mvcInnerResolver.GetService(serviceType);
        return result;
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        IEnumerable<object> result = this.serviceProvider.GetServices(serviceType);
        if (result == null && mvcInnerResolver != null)
            result = mvcInnerResolver.GetServices(serviceType);
        return result ?? new object[0];
    }
}

自定义解析器就位后,您现在可以配置应用程序以使用它。

以您当前的示例为起点(评论评论)

protected void Application_Start() {
    var services = new ServiceCollection();
    ConfigureServices(services);
    //build service provider
    IServiceProvider provider = services.BuildServiceProvider();
    //Get the current resolver used by MVC
    var current = DependencyResolver.Current;
    //use that and the provider to create your custom resolver
    var resolver = new CoreDependencyResolver(provider, current);
    //now set the MVC framework to use the resolver that wraps the service provider
    //that was created from .Net Core Dependency Injection framework.
    DependencyResolver.SetResolver(resolver);
    //...

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

private void ConfigureServices(IServiceCollection services) {
    //... omitted for brevity (register dependencies as normal)
}

这里我使用的是 Oracle,但你也可以用 SQL Server 做同样的事情...

 public void ConfigureServices(IServiceCollection services)
 {

        services.AddEntityFrameworkOracle()
            .AddDbContext<OracleDbContext>(builder => builder.UseOracle(Configuration["Data:OracleDbContext"]),ServiceLifetime.Scoped)
            .AddDbContext<AppsDbContext>(option => option.UseOracle(Configuration["Data:AppsDbConnection:ConnectionString"]), ServiceLifetime.Scoped);

然后在我的 appsettings.json 中包含连接字符串...

"Data": {
"OracleDbContext": "your connection string" },
"AppsDbContext": "your connection string" }
 }

虽然使用带有完整框架的 .NET Core 工具效果很好,但如果您必须使用 MVC5 和完整框架,我不会尝试那样做。

.NET 4.6.1依赖注入框架有很多,本例中我将使用Autofac。

  • 安装 NuGet 包 AutofacAutofac.Mvc5
  • AutofacRegistration.cs class 添加到 App_Start 文件夹
  • Global.asaxApplication_Start() 方法中添加行 AutofacRegistration.BuildContainer();

您的 AutofacRegistration class 是您连接所有依赖项以进行依赖项注入的地方。完整的文档在这里 https://autofaccn.readthedocs.io/en/latest/integration/mvc.html

public class AutofacRegistration
{
    public static void BuildContainer()
    {
        var builder = new ContainerBuilder();

        // Register your MVC controllers
        builder.RegisterControllers(typeof(MvcApplication).Assembly);

        // Now grab your connection string and wire up your db context
        var conn = ConfigurationManager.ConnectionStrings["BloggingContext"];
        builder.Register(c => new BloggingContext(conn));

        // You can register any other dependencies here

        // Set the dependency resolver to be Autofac.
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

这是假设您的 BloggingContext 有一个将连接字符串作为参数并将其传递给基础 class 的构造函数。像

public class BloggingContext : DbContext
{
    public BloggingContext(string connectionString) : base(connectionString)
    {
    }
}

关于范围等的文档中有更多内容值得一读,但这应该是它的基本要素。

看来您使用的是 .Net Framework,而不是 .Net Core。

这里有 2 个简单的想法:

  • 将 DbContext 注入服务层:该层将是 class .Net Framework 库或(如果您的平台是 .Net Core,则使用 .Net Standard Class 库)。此线程向您展示了如何执行它:
  • 如果您使用的是 .Net Framework 平台,请使用 Ninject 作为依赖注入器。这个线程显示了一个很好的例子:How to handle DBContext when using Ninject