是否有另一种方法可以为正在注入的记录器声明我的ProductController?
public class ProductController : Controller
{
private readonly LoggingInterface.ILogger<ProductController> _logger;
private readonly IProductRepository _productRepository;
public ProductController(LoggingInterface.ILogger<ProductController> logger, IProductRepository productRepository)
{
_logger = logger;
_productRepository = productRepository;
}
{
谢谢你, 斯蒂芬
答案 0 :(得分:2)
推理需要使用开放式泛型。此示例中没有
答案 1 :(得分:0)
如果我没弄错的话,你希望做什么(希望你能做到)是这样的:
class ProductController<T> : Controller where T : ProductController
{
ILogger<T> _logger;
... etc
}
我认为如果从设计中稍微退一步,就可以获得相当灵活的界面。这里有三个部分 - 控制器,记录器,控制器和记录器的对象,我将其称为数据传输对象。所以,你有“产品控制器”和“产品记录器”(你现在称之为“产品控制器记录器”)。
假设你有这个DTO对象结构:
public class DataTransferBase { /*This is what both logger and controller operate on*/ }
public class Product : DataTransferBase { }
现在,为什么记录器和控制器都不关心DTO,而不是记录器本身与控制器有关?所以记录器就像:
public interface ILogger
{
void Log(string message);
}
public interface ILogger<T> : ILogger where T : DataTransferBase
{
void Log(T item);
}
public class FileLogger<T> : ILogger<T> where T : DataTransferBase
{
public virtual void Log(T item) { /* Write item.ToString() to a file or something */ }
public void Log(string message) { /* Write the string to a file */ }
}
......和控制器就像:
public interface IController<T> where T : DataTransferBase {}
public class Controller<T> : IController<T> where T : DataTransferBase
{
/// <summary>Initializes a new instance of the ProductController class.</summary>
public Controller(ILogger<T> logger)
{
}
public virtual List<T> GetItems()
{
return new List<T>();
}
}
你现在拥有的是一个记录器,它可以在任何DTO和一个可以在任何DTO上运行的控制器上运行,并且该控制器恰好作为构造函数参数,一个将在与它相同的DTO上运行的记录器。现在,您可以根据需要进行更具体的实施:
public class ProductFileLogger : FileLogger<Product>
{
public override void Log(Product item) { /* Get all specific with item */}
}
和
public class ProductController : Controller<Product>
{
/// <summary>
/// Initializes a new instance of the ProductController class.
/// </summary>
public ProductController(ILogger<Product> productLogger) : base(productLogger) { }
public override List<Product> GetItems()
{
return new List<Product>();
}
}
并且,您可以根据需要特别或一般地将它们连接起来:
public class Client
{
private void DoSomething()
{
IController<Product> myController = new ProductController(new ProductFileLogger()); //If you want to be specific
IController<Product> myController2 = new Controller<Product>(new ProductFileLogger()); //If you want a generic controller and specific logger
IController<Product> myController3 = new Controller<Product>(new FileLogger<Product>()); //If you want to be as generic as possible
}
}
请注意,我只是在飞行中煽动它,所以它可能不是最佳的,但我只是想传达一般的想法。您不能声明具有泛型类型的类(据我所知),但您可以在同一泛型类型上运行两个类交互(控制器和记录器)。也就是说,IController可以拥有一个ILogger,当你实例化IController时,你强制它的记录器在同一类型上运行。