ASP.NET MVC 5 の依存性注入を作成するにはどうすればいいですか? 質問する

ASP.NET MVC 5 の依存性注入を作成するにはどうすればいいですか? 質問する

ASP.NET Coreで依存性注入を作成するのはかなり簡単です。ドキュメントで非常にわかりやすく説明されています。ここそしてこの男はキラービデオそれを説明するために。

しかし、ASP.NET MVC 5 プロジェクトでも同じことを実行したいと考えています。ASP.MVC 5 で依存性注入を処理するにはどうすればよいですか?

また、依存性注入はコントローラーのみに限定されますか、それともどのクラスでも機能しますか?

ベストアンサー1

ASP.Net MVC では、サードパーティの代替品ではなく、NuGet の .Net Core DI を使用できます。

using Microsoft.Extensions.DependencyInjection

MVC スタート/構成クラスの場合:-

public void Configuration(IAppBuilder app)
{
    // We will use Dependency Injection for all controllers and other classes, so we'll need a service collection
    var services = new ServiceCollection();

    // configure all of the services required for DI
    ConfigureServices(services);

    // Configure authentication
    ConfigureAuth(app);

    // Create a new resolver from our own default implementation
    var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());

    // Set the application resolver to our default resolver. This comes from "System.Web.Mvc"
    //Other services may be added elsewhere through time
    DependencyResolver.SetResolver(resolver);
}

私のプロジェクトでは Identity User を使用しており、OWIN の起動構成をサービスベースのアプローチに置き換えました。デフォルトの Identity User クラスは、静的ファクトリ メソッドを使用してインスタンスを作成します。そのコードをコンストラクターに移動し、DI を使用して適切なインジェクションを提供しました。まだ作業中ですが、現在のところは次のようになります。

public void ConfigureServices(IServiceCollection services)
{               
    //====================================================
    // Create the DB context for the IDENTITY database
    //====================================================
    // Add a database context - this can be instantiated with no parameters
    services.AddTransient(typeof(ApplicationDbContext));

    //====================================================
    // ApplicationUserManager
    //====================================================
    // instantiation requires the following instance of the Identity database
    services.AddTransient(typeof(IUserStore<ApplicationUser>), p => new UserStore<ApplicationUser>(new ApplicationDbContext()));

    // with the above defined, we can add the user manager class as a type
    services.AddTransient(typeof(ApplicationUserManager));

    //====================================================
    // ApplicationSignInManager
    //====================================================
    // instantiation requires two parameters, [ApplicationUserManager] (defined above) and [IAuthenticationManager]
    services.AddTransient(typeof(Microsoft.Owin.Security.IAuthenticationManager), p => new OwinContext().Authentication);
    services.AddTransient(typeof(ApplicationSignInManager));

    //====================================================
    // ApplicationRoleManager
    //====================================================
    // Maps the rolemanager of identity role to the concrete role manager type
    services.AddTransient<RoleManager<IdentityRole>, ApplicationRoleManager>();

    // Maps the role store role to the implemented type
    services.AddTransient<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>();
    services.AddTransient(typeof(ApplicationRoleManager));
    
    //====================================================
    // Add all controllers as services
    //====================================================
    services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
        .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
    .Where(t => typeof(IController).IsAssignableFrom(t)
    || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
}

Account Controller クラスには、1 つのコンストラクターがあります:

[Authorize]
public class AccountController : Controller
{
    private ApplicationSignInManager _signInManager;
    private ApplicationUserManager _userManager;
    private RoleManager<IdentityRole> _roleManager;

    public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, RoleManager<IdentityRole> roleManager)
    {
        UserManager = userManager;
        SignInManager = signInManager;
        RoleManager = roleManager;
    }
}

私のデフォルトの依存関係リゾルバー:

/// <summary>
/// Provides the default dependency resolver for the application - based on IDependencyResolver, which hhas just two methods
/// </summary>
public class DefaultDependencyResolver : IDependencyResolver
{
    /// <summary>
    /// Provides the service that holds the services
    /// </summary>
    protected IServiceProvider serviceProvider;

    /// <summary>
    /// Create the service resolver using the service provided (Direct Injection pattern)
    /// </summary>
    /// <param name="serviceProvider"></param>
    public DefaultDependencyResolver(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    /// <summary>
    /// Get a service by type - assume you get the first one encountered
    /// </summary>
    /// <param name="serviceType"></param>
    /// <returns></returns>
    public object GetService(Type serviceType)
    {
        return this.serviceProvider.GetService(serviceType);
    }

    /// <summary>
    /// Get all services of a type
    /// </summary>
    /// <param name="serviceType"></param>
    /// <returns></returns>
    public IEnumerable<object> GetServices(Type serviceType)
    {
        return this.serviceProvider.GetServices(serviceType);
    }
}

おすすめ記事