C# Autofac-通过控制器构造函数参数解析泛型类型

C# Autofac-通过控制器构造函数参数解析泛型类型,c#,generics,dependency-injection,constructor,autofac,C#,Generics,Dependency Injection,Constructor,Autofac,我有抽象泛型类 public abstract class AbstractLogic<T> {} 现在我需要在DI的帮助下创建它们中每一个的实例。 所以,我注册了这样的类型 var logicList= new[] { Assembly.GetAssembly(typeof(DefaultLogic)), Assembly.GetAssembly(typeof(SpecificLogic))

我有抽象泛型类

 public abstract class AbstractLogic<T> {}
现在我需要在DI的帮助下创建它们中每一个的实例。 所以,我注册了这样的类型

    var logicList= new[]
        {
            Assembly.GetAssembly(typeof(DefaultLogic)),
            Assembly.GetAssembly(typeof(SpecificLogic))
        };
        builder.RegisterAssemblyTypes(logicList).AsClosedTypesOf(typeof(AbstractLogic<>))
            .Where(t => t.Name.StartsWith(Settings.GetCurrentMode().ToString()));
var logicList=new[]
{
Assembly.GetAssembly(typeof(DefaultLogic)),
Assembly.GetAssembly(typeof(SpecificLogic))
};
RegisterAssemblyTypes(logicList).AsClosedTypesOf(typeof(AbstractLogic))
.Where(t=>t.Name.StartsWith(Settings.GetCurrentMode().ToString());
Settings.GetCurrentMode()-返回我需要的实例的名称(默认为Specific)

不,我想将服务注入控制器,使其能够加载所需的逻辑服务

public class ListController : Controller
{
    private AbstractLogic<???> _logic;
    public ListController(AbstractLogic<???> logic)
        {
            _logic = logic;
        }

}
公共类ListController:控制器
{
私有抽象逻辑;
公共ListController(抽象逻辑)
{
_逻辑=逻辑;
}
}

编译器要求我定义模型而不是???。但是,我不需要它,因为抽象类的实现已经选择了开放泛型类型而不是继承。是否有其他方法可以使用autofac解决所需的逻辑问题?

我认为您在这里有三个左右的实际选项

1) 将控制器设为泛型,然后将控制器的类型参数传递给注入的类型本身(见下文)。通过这种方式,控制器将知道特定类型的
T
,并且能够在没有任何奇怪舞蹈的情况下使用它。然而,下一个问题是——如何向一个将要解决这样一个控制器的框架解释所有这些东西?默认情况下,DotNet Core不支持通用控制器。幸运的是,这是很有可能做到这一点。您可以阅读有关它的一些详细信息,并通过。但这并不简单,所以这对你的任务来说可能是过度的。。。我只是不确定你的任务到底是什么

[Route("api/[controller]")]
public class ValuesController<T> : Controller where T: class, new()
{
    private readonly AbstractLogic<T> _logic;

    public ValuesController(AbstractLogic<T> logic)
    {
        _logic = logic;
    }

回答这个问题会有帮助:谢谢,我不认为这是一样的…你应该使用非泛型基类或接口。你的
ListController
不在乎,所以它显然不是泛型的。@Steven是对的。此外,如果编译器有什么要求,Autofac也不能帮助您解决这个问题。
public class ListController : Controller
{
    private AbstractLogic<???> _logic;
    public ListController(AbstractLogic<???> logic)
        {
            _logic = logic;
        }

}
[Route("api/[controller]")]
public class ValuesController<T> : Controller where T: class, new()
{
    private readonly AbstractLogic<T> _logic;

    public ValuesController(AbstractLogic<T> logic)
    {
        _logic = logic;
    }
// class hierarchy
public abstract class AbstractLogic
{
    public string DoStufF()
    {
        return DoStufFInternal();
    }

    protected abstract string DoStufFInternal();
}

// Here 'where' constraint is not essential, I'm just lazy enough
// and implemented property setting in the dumbest possible way which required the constraint :)
public abstract class AbstractLogic<T> : AbstractLogic where T: class, new()
{
    protected AbstractLogic()
    {
        SomeProperty = new T();
    }

    public T SomeProperty { get; private set; }
}

public class DefaultLogic : AbstractLogic<ClassA>
{
    protected override string DoStufFInternal()
    {
        return $"Default stuff: SomeProperty = {SomeProperty.ToString()}";
    }
}

public class SpecificLogic : AbstractLogic<ClassB>
{
    protected override string DoStufFInternal()
    {
        return $"Specific stuff: SomeProperty = {SomeProperty.ToString()}";
    }
}

public class ClassA
{
    public override string ToString()
    {
        return "Class A representation";
    }
}

public class ClassB
{
    public override string ToString()
    {
        return "Class B representation";
    }
}

// registering class
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
    .Where(t => t.Name.StartsWith(Settings.GetCurrentMode().ToString()))
    .As<AbstractLogic>()
    .InstancePerLifetimeScope();

// and using it in the controller
[Route("api/[controller]")]
public class DITestController : Controller
{
    private readonly AbstractLogic _logic;

    public DITestController(AbstractLogic logic)
    {
        _logic = logic;
    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(_logic.DoStufF());
    }
}