Si no me equivoco, lo que busca hacer (deseando poder hacerlo) es algo así como:
class ProductController<T> : Controller where T : ProductController
{
ILogger<T> _logger;
... etc
}
creo que puede obtener una interfaz bastante flexible si se aleja un poco de su diseño. Aquí tiene tres partes: un controlador, un registrador y el objeto del controlador y el registrador, que llamaré un objeto de transferencia de datos. Entonces, tiene "controlador de producto" y "registrador de producto" (que actualmente llama "registrador de controlador de producto").
Digamos que usted tiene esta estructura de objetos DTO:
public class DataTransferBase { /*This is what both logger and controller operate on*/ }
public class Product : DataTransferBase { }
Ahora, en lugar del registrador en relación con los controladores en sí, ¿por qué no tiene el registrador y el controlador tanto a sí mismos preocupación por dtos? Así es como registrador:
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 */ }
}
... y el controlador es como:
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>();
}
}
Lo que tenemos aquí ahora es un registrador que operará en cualquier DTO y un controlador que operará en cualquier DTO , y ese controlador pasa a tomar como parámetro constructor, un registrador que operará en el mismo DTO que lo hace. Ahora, usted puede tener implementaciones más específicas si se quiere:
public class ProductFileLogger : FileLogger<Product>
{
public override void Log(Product item) { /* Get all specific with item */}
}
y
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>();
}
}
Y, se puede conectar éstos como términos generales o específicos a su gusto:
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
}
}
favor tenga en cuenta que, simplemente, como que lo preparé sobre la marcha, por lo que puede no ser óptimo, pero estoy tratando de transmitir la idea general. No se puede declarar una clase con un tipo genérico de sí mismo (hasta donde sé), pero puede tener dos clases interactuando (controlador y registrador) que operan en el mismo tipo genérico. Es decir, IController puede ser propietario de un ILogger y cuando crea una instancia de IController, fuerza a su registrador a operar del mismo tipo.
¿Correcto de qué manera? –
Inferencia requiere el uso de un genérico abierto. No hay ninguno en esta muestra – JaredPar
Supongo que podría editar el título y preguntar un poco –