简体   繁体   English

使用依赖注入在哪里注册上下文

[英]Where to register the context with dependency injection

According to this tutorial I should: 根据教程,我应该:

Register your context with dependency injection

The Tutorial describes that I should locate the method ConfigureServices() and put in there the code advised. 该教程描述了我应该找到方法ConfigureServices()并在其中放置建议的代码。

Here's my startup.cs : 这是我的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);
        }
    }
}

so I don't know where to correctly put the code. 所以我不知道在哪里正确放置代码。

Because the project isn't compatible with .net core 2.1, it was needed to change Project->Property to .Net Framework 4.6.1 and install packages Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.Tools 由于该项目与.net core 2.1不兼容,因此需要将Project-> Property更改为.Net Framework 4.6.1并安装软件包Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.Tools

I tried to add the dependency injection to global.asax.cs file as follows: 我尝试将依赖项注入添加到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));
    }

I succeeded with the step and created the controller and it works, but I haven't chosen the right context (BloggingContext), so it created second database. 我成功完成了该步骤并创建了控制器,并且该控制器可以工作,但是我没有选择正确的上下文(BloggingContext),因此它创建了第二个数据库。 So, I need to create a controller with BloggingContext, do you know how? 因此,我需要使用BloggingContext创建一个控制器,您知道如何吗?

The version of the shown startup and the tutorial are in conflict with each other. 所示的启动版本和教程相互冲突。

If this if for an Asp.Net Core MVC application then you can add the method your self. 如果是Asp.Net Core MVC应用程序,则可以自行添加该方法。 Startup class is part of the convention. Startup类是约定的一部分。

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)
    {
         //...
    }
}

Reference App startup in ASP.NET Core 在ASP.NET Core中参考应用程序启动

The ConfigureServices method ConfigureServices方法

The ConfigureServices method is: ConfigureServices方法是:

  • Optional. 可选的。
  • Called by the host before the Configure method to configure the app's services. 由主机在Configure方法之前调用,以配置应用程序的服务。
  • Where configuration options are set by convention. 按照约定设置配置选项的位置。

If however you are trying to use .Net Core technologies in an Asp.Net MVC 5+ (which is what the GitHub project targets) then you will need to modify your approach to adapt to using .Net Core Dependency Injection with a non core platform. 但是,如果您试图在Asp.Net MVC 5+中使用.Net Core技术(这是GitHub项目的目标),那么您将需要修改您的方法以适应在非核心平台上使用.Net Core Dependency Injection。 。

First you will need a IDependencyResolver which is the DI framework used by that version of Asp.Net MVC, and a way to replace the default resolver with your own. 首先,您需要一个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];
    }
}

With the custom resolver in place, you can now configure the application to use it. 使用自定义解析器后,您现在可以配置应用程序以使用它。

Using your current example as a starting point (review comments) 以您当前的示例为起点(评论)

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)
}

Here I am using Oracle, but you could do the same with SQL Server... 在这里,我使用的是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);

Then in my appsettings.json, I include the connection strings... 然后在我的appsettings.json中,包括连接字符串...

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

Whilst using .NET Core tooling with full framework works quite well, if you have to use MVC5 and full framework I would not try to work it that way round. 虽然将.NET Core工具与完整框架一起使用会很好,但是如果必须使用MVC5和完整框架,我不会尝试那样处理。

There are many .NET 4.6.1 dependency injection frameworks, in this example I will use Autofac. 有许多.NET 4.6.1依赖项注入框架,在本示例中,我将使用Autofac。

  • Install the NuGet packages Autofac and Autofac.Mvc5 . 安装NuGet包AutofacAutofac.Mvc5
  • Add an AutofacRegistration.cs class to the App_Start folder 将一个AutofacRegistration.cs类添加到App_Start文件夹中
  • In the Application_Start() method in Global.asax add the line AutofacRegistration.BuildContainer(); Global.asaxApplication_Start()方法中,添加行AutofacRegistration.BuildContainer();

Your AutofacRegistration class is where you wire up all your dependencies for dependency injection. AutofacRegistration类中,可以连接所有依赖项以进行依赖项注入。 The full docs are here https://autofaccn.readthedocs.io/en/latest/integration/mvc.html 完整的文档在这里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));
    }
}

This is assuming your BloggingContext has a constructor that takes the connection string as a parameter and passes it to the base class. 假设您的BloggingContext具有一个构造函数,该构造函数将连接字符串作为参数并将其传递给基类。 Something like 就像是

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

There is loads more in the documentation about scope etc that is worth reading but this should be the nuts and bolts of it. 关于范围等的文档中还有很多值得阅读的内容,但这应该是它的基本内容。

It appears you're using .Net Framework, rather than .Net Core. 看来您使用的是.Net Framework,而不是.Net Core。

2 simple ideas here: 这里有2个简单的想法:

  • Injecting DbContext into service layer: this layer will be class Library for .Net Framework or (use .Net Standard Class library if your platform is .Net Core). 将DbContext注入服务层:该层将是.Net Framework的类库,或者(如果您的平台是.Net Core,则使用.Net标准类库)。 This thread shows you how to perform it: Injecting DbContext into service layer 此线程向您展示如何执行它: 将DbContext注入服务层
  • use Ninject as dependency injector if you're on .Net Framework platform. 如果您在.Net Framework平台上,请使用Ninject作为依赖项注入器。 This thread shows a good example: How to handle DBContext when using Ninject 该线程显示了一个很好的示例: 使用Ninject时如何处理DBContext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM