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

时间:2017-08-14 01:09:41

标签: c# dependency-injection asp.net-core

我有一个2控制器PayerController和BusinessController。 两个Controller构造函数都将EntityManager作为一个抽象类参数。 我想根据我使用的控制器解析每个Manager类。

对于PayerController,我想注入PayerManager类,对于BusinessController,我想注入BusinessManager。

Currentlly我得到了最后一个用EntityManager解析的Object,即BusinessManager。

我记得在Ninject中我们可以很容易地进行条件注射。

这是当前我解决依赖的方式但不会工作。

Startup.cs

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

控制器

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

经理类

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

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

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

3 个答案:

答案 0 :(得分:2)

我不明白为什么你认为在这种情况下需要条件依赖注入,因为使其工作的解决方案非常简单。

您可以更改控制器以注入所需的正确依赖类型。

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

然后确保两种类型都已在服务容器中注册。

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

<强>更新

更好的方法是使用接口和可能的抽象通用控制器。

定义界面:

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

更新您的类以实现接口:

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

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

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

然后创建一个基本控制器类:

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

    protected T Manager { get; }
}

将控制器更改为从基本控制器继承:

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

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

更新服务注册表:

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

答案 1 :(得分:1)

为每个具体类创建接口并在控制器中注入接口

<强> Startup.cs

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

<强>控制器

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

经理类

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

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

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

<强>接口

public interface IPayerManager
{
    void MyPayer();
}

public interface IBusinessManager
{
    void MyBusiness();
}

答案 2 :(得分:0)

@Maxspan,我的建议:

将所有接口放置在Contracts文件夹中,并将此文件夹放置在Models / Entities文件夹中(Models / Entities文件夹-Contracts文件夹)

IEntityManager界面

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

IBusinessManager界面

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

IPayerManager界面

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

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具体课程

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

启动类

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