1
votes

Où enregistrer le contexte avec l'injection de dépendances

Selon ceci tutoriel Je devrais:

Enregistrer votre contexte avec l'injection de dépendances

Le tutoriel décrit que je dois localiser la méthode ConfigureServices () et mettez-y le code conseillé.

Voici mon startup.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));
    }

donc je ne sais pas où mettre correctement le code.

Le projet n'étant pas compatible avec .net core 2.1, il était nécessaire de changer Project-> Property en .Net Framework 4.6.1 et installez les packages Microsoft.EntityFrameworkCore.SqlServer et Microsoft.EntityFrameworkCore.Tools

J'ai essayé d'ajouter l'injection de dépendance à global.asax.cs fichier comme suit:

using Microsoft.Owin;
using Owin;

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

J'ai réussi l'étape et créé le contrôleur et cela fonctionne, mais je n'ai pas choisi le bon contexte (BloggingContext), donc il a créé une deuxième base de données. Donc, j'ai besoin de créer un contrôleur avec BloggingContext, savez-vous comment?


11 commentaires

Vous pouvez ajouter la méthode vous-même. La classe Startup fait partie de la convention de démarrage.


La version du démarrage affiché et le didacticiel sont en conflit l'un avec l'autre.


@Nkosi J'ai changé dans Projet-> Propriété en .Net Framework 4.6.1


@Nkosi, il était également nécessaire d'installer dans PMC Microsoft.EntityFrameworkCore.SqlServer et Microsoft.EntityFrameworkCore.Tools


Vous devriez essayer Ninject pour l'injection de dépendances. Cela fonctionne bien avec .Net Framework 4.6. L'implémentation de l'injection de dépendances diffère pour .Net core et .Net. Je ne suis pas sûr qu'il soit entièrement intégré dans .Net Framework comme .Net Core l'a fait. vous pourriez avoir besoin de Ninject ou Unity


@Bosco Ici est écrit qu'il devrait travail.


Vous avez un projet MVC régulier mais vous souhaitez utiliser EF Core, pourquoi? Utilisez EF 6 et consultez les didacticiels pour le ninject ASP.NET MVC


Le contexte que vous voyez lors de la création d'un contrôleur en mode conception est enregistré dans le web.config, encore une fois l'instanciation de BlogContext dans un contrôleur va à l'encontre de l'objectif de DI, vous devriez utiliser des interfaces. le ConfigureService est ajouté dans Startup.cs


Utilisez-vous .Net Framework ou .Net Core? Je vous suggère de rechercher les différences. Si finalement vous souhaitez utiliser .Net Core, je vous propose d'utiliser .net core dans toutes vos recherches.


Y a-t-il une raison particulière pour laquelle vous devez mélanger les deux technologies? Pourquoi ne pas utiliser un package .NET Framework DI comme Autofac / StructureMap, etc. Tout cela fonctionne correctement en injectant un DbContext via une injection de constructeur.


@ ste-fu s'il vous plaît écrivez-le comme une réponse, afin que je puisse essayer, si elle trouve le BloggingContext


4 Réponses :


1
votes

La version de démarrage affichée et le didacticiel sont en conflit l'un avec l'autre.

S'il s'agit d'une application Asp.Net Core MVC, vous pouvez ajouter la méthode vous-même. La classe Startup fait partie de la convention.

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

Référence Démarrage de l'application dans ASP.NET Core

La méthode ConfigureServices

La méthode ConfigureServices est:

  • Facultatif.
  • Appelé par l'hôte avant la méthode Configure pour configurer les services de l'application.
  • Où les options de configuration sont définies par convention.

Si toutefois vous essayez d'utiliser les technologies .Net Core dans un Asp.Net MVC 5+ (c'est ce que le projet GitHub cible) alors vous devrez modifiez votre approche pour vous adapter à l'utilisation de l'injection de dépendances .Net Core avec une plate-forme non principale.

Tout d'abord, vous aurez besoin d'un IDependencyResolver qui est le framework DI utilisé par cette version d'Asp. Net MVC et un moyen de remplacer le résolveur par défaut par le vôtre.

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];
    }
}

Avec le résolveur personnalisé en place, vous pouvez désormais configurer l'application pour l'utiliser. P >

En utilisant votre exemple actuel comme point de départ (commentaires de révision)

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


7 commentaires

Merci mais il y a quelques lignes rouges dans mon code. Pourriez-vous également montrer la méthode complète avec les espaces de noms?


@xralf vient de remarquer un écart. Le tutoriel est pour Core tandis que l'autre code est pour la version précédente de MVC. Pouvez-vous préciser quelle version vous utilisez.


J'ai changé le framework .net en 4.6.1 dans Project-> Properties, sans cela cela ne fonctionnerait pas.


il était également nécessaire d'installer dans PMC Microsoft.EntityFrameworkCore.SqlServer et Microsoft.EntityFrameworkCore.Tools


Lorsque je colle dans ConfigureServices () seulement ces deux lignes de code var connection = @ "Server = (localdb) \ mssqllocaldb; Database = Blogging; Trusted_Co‌ nnection = True; Connec‌ tRetryCount = 0"; services.AddDbContext (options => options.UseSqlServer (connexion)); J'ai du mal à créer un contrôleur. Cela ne m'offrira pas BloggingContext


Voici mon fichier global.asax.cs . Après Build-> Clean, Build-> Rebuild, cliquez avec le bouton droit sur controllers-> add-> controller-> MVC 5 controller avec vues, en utilisant le framework d'entité ... dans la classe de contexte de données, je ne peux pas choisir BloggingContext


Blogging3 n'est qu'une faute de frappe.



1
votes

Ici, j'utilise Oracle, mais vous pourriez faire la même chose avec SQL Server ...

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

Ensuite, dans mon appsettings.json, j'inclus les chaînes de connexion ... p >

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


0 commentaires

1
votes

Bien que l'utilisation des outils .NET Core avec un framework complet fonctionne assez bien, si vous devez utiliser MVC5 et un framework complet, je n'essaierais pas de le faire de cette façon.

Il existe de nombreux frameworks d'injection de dépendances .NET 4.6.1 , dans cet exemple, j'utiliserai Autofac.

  • Installez les packages NuGet Autofac et Autofac.Mvc5 .
  • Ajouter une classe AutofacRegistration.cs au dossier App_Start
  • Dans la méthode Application_Start () de Global.asax , ajoutez la ligne AutofacRegistration.BuildContainer();

Votre classe AutofacRegistration est l'endroit où vous connectez toutes vos dépendances pour l'injection de dépendances. La documentation complète est ici https://autofaccn.readthedocs.io/en/latest /integration/mvc.html

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

Cela suppose que votre BloggingContext a un constructeur qui prend la chaîne de connexion comme paramètre et passe à la classe de base. Quelque chose comme

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

Il y a beaucoup plus dans la documentation sur la portée, etc. qui vaut la peine d'être lu, mais cela devrait en être les noix et les boulons.


8 commentaires

Merci, je vais essayer demain. Pouvez-vous me dire ce que "MyDbContext"? C'est ma chaîne de connexion? Et MyDbContext = BloggingContext?


Oui. Je les ai appelés la même chose, mais l'un est le nom de la chaîne de connexion et l'autre est votre implémentation de DbContext, qui serait BloggingContext


Il y a un soulignement rouge dans le générateur.Register (c => new BloggingContext (conn); ... conn est souligné comme une erreur


Ok - une autre hypothèse. J'ai supposé que vous aviez implémenté le constructeur avec un paramètre de chaîne ... voir mise à jour


Voici mon fichier autofacRegistration.cs et fichier bloggingContext.cs . Après Build-> Clean, Build-> Rebuild, cliquez avec le bouton droit sur controllers-> add-> controller-> MVC 5 controller avec vues, en utilisant le framework d'entité ... dans la classe de contexte de données, je ne peux pas choisir BloggingContext


OK - supprimez toutes les références au noyau Entity Framework et assurez-vous de référencer Entity Framework 6.x. Supprimez tout sauf le constructeur sans paramètre pour votre BloggingContext et ajoutez-en un avec juste une chaîne comme dans mon exemple


Quels packages nuget dois-je installer pour pouvoir utiliser la commande: Scaffold-DbContext "Server = (localdb) \ mssqllocaldb; Database = Blogging; Trusted_Con‌ nection = True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables Blog, Post Ou une commande similaire


Grâce à vous, j'ai trouvé ce tutoriel, qui fonctionne avec le projet. Je n'ai pas pu le trouver avant.



1
votes

Il semble que vous utilisez .Net Framework, plutôt que .Net Core.

2 idées simples ici:


0 commentaires