简体   繁体   English

Asp.net 核心中的条件依赖解析

[英]Conditional Dependency Resolving in Asp.net core

I am having a 2 controller PayerController and BusinessController.我有一个 2 控制器 PayerController 和 BusinessController。 Both Controller constructors takes EntityManager as a parameter which is an abstract class.两个 Controller 构造函数都将 EntityManager 作为参数,这是一个抽象类。 I would like to resolve Each Manager class depending on the controller I am using.我想根据我使用的控制器解析每个 Manager 类。

For PayerController I would like to inject PayerManager class and for BusinessController I would like to inject BusinessManager.对于 PayerController,我想注入 PayerManager 类,对于 BusinessController,我想注入 BusinessManager。

Currentlly I am getting the last Object that has been resolved with EntityManager ie BusinessManager.目前,我正在获取已使用 EntityManager 解决的最后一个对象,即 BusinessManager。

I remember in Ninject we can do conditional injection pretty easily.我记得在 Ninject 中,我们可以很容易地进行条件注入。

This is how current I am resolving the dependency But wont work.这就是我解决依赖项的当前方式,但无法正常工作。

Startup.cs启动文件

services.AddScoped(typeof(EntityManager), typeof(PayerManager));
services.AddScoped(typeof(EntityManager), typeof(BusinessManager));

Controllers控制器

public class PayerController
{
   private PayerManager Manager{get;}
   public PayerController(EntityManager entityManager)
   {
      Manager = entityManager as PayerManager;
   }
}

Manager Classes经理班

public class PayerManager : EntityManager
{
    public void MyPayer()
    {
    }  
}

public class BusinessManager : EntityManager
{
    public void MyBusiness()
    {
    }
}

public abstract class EntityManager
{
    public string IAMCommon()
    {
        return "";
    }
}

I don't understand why you think you need conditional dependency injection in this situation because the solution to make it work is very simple.我不明白为什么您认为在这种情况下需要条件依赖注入,因为使其工作的解决方案非常简单。

You can change your controllers to inject the correct type of dependency that they need.您可以更改控制器以注入他们需要的正确类型的依赖项。

public class PayerController
{
   private PayerManager Manager { get; }

   public PayerController(PayerManager manager)
   {
      Manager = manager;
   }
}

public class BusinessController
{
   private BusinessManager Manager { get; }

   public BusinessController(BusinessManager manager)
   {
      Manager = manager;
   }
}

Then make sure both types are registered in the service container.然后确保这两种类型都在服务容器中注册。

services.AddScoped<PayerManager>();
services.AddScoped<BusinessManager>();

UPDATE更新

A better way is to use interfaces and possibly an abstract generic controller.更好的方法是使用接口和可能的抽象通用控制器。

Define your interfaces:定义你的接口:

public interface IEntityManager { }
public interface IPayerManager : IEntityManager { }
public interface IBusinessManager : IEntityManager { }

Update your classes to implement the interfaces:更新您的类以实现接口:

public abstract class EntityManager : IEntityManager 
{ 
    protected EntityManager() { }
}

public class PayerManager : EntityManager, IPayerManager 
{ 
    public PayerManager() : base() { }
}

public class BusinessManager : EntityManager, IBusinessManager 
{ 
    public BusinessManager() : base() { }
}

Then create a base controller class:然后创建一个基本控制器类:

public abstract class EntityController<T> : Controller where T : class, IEntityManager
{
    protected(T manager)
    {
        Manager = manager
    }

    protected T Manager { get; }
}

Change your controllers to inherit from base controller:更改您的控制器以从基本控制器继承:

public class PayerController : EntityController<IPayerManager>
{
   public PayerController(IPayerManager manager) : base(manager) { }
}

public class BusinessController : EntityController<IBusinessManager>
{
   public BusinessController(IBusinessManager manager) : base(manager) { }
}

And update the service register:并更新服务寄存器:

services.AddScoped<IPayerManager, PayerManager>();
services.AddScoped<IBusinessManager, BusinessManager>();

Make interface for each concrete class and Injecting interface in the controller为控制器中的每个具体类和注入接口制作接口

Startup.cs启动文件

services.AddScoped<IPayerManager, PayerManager>();
services.AddScoped<IBusinessManager, BusinessManager>();

Controllers控制器

public class PayerController
{
    private IPayerManager _entityManager{get;}
    public PayerController(IPayerManager entityManager)
   {
       _entityManager= entityManager;
   }
}


public class BusinessController
{
    private IBusinessManager _entityManager{get;}
    public BusinessController(IBusinessManager entityManager)
   {
       _entityManager= entityManager;
   }
}

Manager Classes经理班

public class PayerManager : EntityManager,IPayerManager 
{
    public void MyPayer()
    {
    }
}

 public class BusinessManager : EntityManager,IBusinessManager 
 {
     public void MyBusiness()
     {
     }
 }

 public abstract class EntityManager
 {
     public string IAMCommon()
     {
         return "";
     }
 }

Interfaces接口

public interface IPayerManager
{
    void MyPayer();
}

public interface IBusinessManager
{
    void MyBusiness();
}

@Maxspan, my suggestion: @Maxspan,我的建议:

Put all interfaces in Contracts folder and this folder inside your Models/Entities folder (Models/Entities folder - Contracts folder)将所有接口放在 Contracts 文件夹中,并将此文件夹放在 Models/Entities 文件夹中(Models/Entities 文件夹 - Contracts 文件夹)

IEntityManager Interface实体管理器接口

namespace WebApplication1.Entities.Contracts
{
    public interface IEntityManager
    {
        //Method signature only
        string IAMCommon();
    }
}

IBusinessManager Interface商务管理界面

namespace WebApplication1.Entities.Contracts
{
    public interface IBusinessManager : IEntityManager
    {
        //Method signature only
        void MyBusiness();
    }
}

IPayerManager Interface IPayerManager 接口

namespace WebApplication1.Entities.Contracts
{
    public interface IPayerManager : IEntityManager
    {
        //Method signature only
        void MyPayer();
    }
}

BusinessManager Concrete Class BusinessManager 具体类

using System;
using WebApplication1.Entities.Contracts;

namespace WebApplication1.Entities
{
    public class BusinessManager : IBusinessManager
    {
        //Method signature in IEntityManager
        public string IAMCommon()  //Heritage in IBusinessManager (IBusinessManager : IEntityManager)
        {
            //Implement your code here.
            throw new NotImplementedException();
        }

        //Method signature in IBusinessManager
        public void MyBusiness() 
        {
            //Implement your code here.
            throw new NotImplementedException();
        }
    }
}

PayerManager Concrete Class PayerManager 具体类

using System;
using WebApplication1.Entities.Contracts;

namespace WebApplication1.Entities
{
    public class PayerManager : IPayerManager
    {
        //Method signature in IEntityManager
        public string IAMCommon() //Heritage in IPayerManager (IPayerManager : IEntityManager)
        {
            //Implement your code here.
            throw new NotImplementedException();
        }

        //Method signature in IPayerManager
        public void MyPayer()
        {
            //Implement your code here.
            throw new NotImplementedException();
        }
    }
}

Startup class创业班

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using WebApplication1.Entities;
using WebApplication1.Entities.Contracts;

namespace WebApplication1
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IBusinessManager, BusinessManager>();
            services.AddScoped<IPayerManager, PayerManager>();
        }
    }
}

BusinessController业务控制器

using Microsoft.AspNetCore.Mvc;
using WebApplication1.Entities.Contracts;

namespace WebApplication1.Controllers
{
    public class BusinessController : Controller
    {
        private readonly IBusinessManager _businessManager;

        public BusinessController(IBusinessManager businessManager)
        {
            _businessManager = businessManager;
        }

        public IActionResult Index()
        {
            //Both methods in BusinessManager due to heritage (BusinessManager : IBusinessManager)
            _businessManager.IAMCommon(); 
            _businessManager.MyBusiness();

            return View();
        }
    }
}

PayerController付款人控制器

using Microsoft.AspNetCore.Mvc;
using WebApplication1.Entities.Contracts;

namespace WebApplication1.Controllers
{
    public class PayerController : Controller
    {
        private readonly IPayerManager _payerManager;

        public PayerController(IPayerManager payerManager)
        {
            _payerManager = payerManager;
        }

        public IActionResult Index()
        {
            //Both methods in PayerManager due to heritage (PayerManager : IPayerManager)
            _payerManager.IAMCommon(); 
            _payerManager.MyPayer(); 

            return View();
        }
    }
}

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

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