通过依赖项注入在哪里注册上下文

时间:2019-08-08 12:51:47

标签: c# asp.net-mvc dependency-injection scaffolding asp.net-mvc-scaffolding

根据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-> Property更改为.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创建一个控制器,您知道如何吗?

4 个答案:

答案 0 :(得分:1)

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

如果是Asp.Net Core MVC应用程序,则可以添加自己的方法。 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)
    {
         //...
    }
}

引用App startup in ASP.NET Core

  

ConfigureServices方法

     

ConfigureServices方法为:

     
      
  • 可选。
  •   
  • 在配置方法之前由主机调用   配置应用程序的服务。
  •   
  • 按照约定设置配置选项的地方。
  •   

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

首先,您需要一个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)
}

答案 1 :(得分:1)

这里我使用的是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" }
 }

答案 2 :(得分:1)

虽然将.NET Core工具与完整框架一起使用效果很好,但是如果您必须使用MVC5和完整框架,我不会尝试那样处理。

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

  • 安装NuGet软件包AutofacAutofac.Mvc5
  • AutofacRegistration.cs类添加到App_Start文件夹中
  • Application_Start()的{​​{1}}方法中,添加行Global.asax

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

AutofacRegistration

这是假设您的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

文档中还有很多有关范围等方面的内容,值得一读,但这应该是它的基本内容。

答案 3 :(得分:1)

似乎您使用的是.Net Framework,而不是.Net Core。

这里有2个简单的想法:

相关问题