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