Как сделать кэширование и внедрение зависимостей вне контроллера в .NET Core MVC - PullRequest
0 голосов
/ 11 октября 2018

Я использовал DI исключительно для тестов в контроллере, и мне странно трудно использовать его вне контроллера.У меня был статический класс кэширования, называемый механизмом кэширования, но, очевидно, классы DI и статические классы не очень хорошо сочетаются друг с другом, поэтому я решил сделать его нестатичным.Тем не менее, я не могу заставить это работать хорошо, и я не уверен, что лучший подход.У меня есть контроллер, который мне нужен для передачи продуктов и отправки их на просмотр.Тем не менее, для повышения скорости я бы хотел использовать кеширование памяти, но я действительно запутался в лучшем дизайне здесь.Я хотел бы знать лучший способ сделать это.

1) Как создание экземпляра нового класса работает с DI, если вы не передаете зависимости?

2) Должен ли я вставить свой кэш памяти и репозиторий продуктов в контроллер, а затем передать их в конструктор cachingengine?Кажется, это лишняя передача параметров, поэтому мне это не понравилось.

3) Должен ли я просто создать экземпляр класса MemoryCache в движке кэширования и не беспокоиться о DI?

4) Должен ли я просто переключить CachingEngine обратно на статический класс?

Спасибо за вашу помощь и советы.Это высоко ценится.

Вот Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        //Add Dependencies
        services.AddTransient<IProductRepository, ProductRepository>();

        //Extention method that sets up the shared objects used in MVC apps
        services.AddMvc();
        services.AddMemoryCache();
        ....
    }
}

Вот контроллер

public class MainController : Controller
{
    private CachingEngine engine;

    public MainController()
    {
        //This isn't valid, missing parameters
        engine = new CachingEngine();
    }

    public IActionResult Index()
    {
        var products = CachingEngine.GetProducts();
        ....
    }
}

А вот класс кэширования:

public class CachingEngine
{
    private readonly IMemoryCache memoryCache;
    private IProductRepository prodRepo;

    public CachingEngine(IMemoryCache memory, IProductRepository rep)
    {
        memoryCache = memoryCache;
        prodRepo = rep;
    }

    public List<Product> GetProducts()
    {
        var cacheKey = "Products";
        List<Product> prods;
        if (memoryCache.TryGetValue(cacheKey, out prods))
        {
            return prods;
        }
        else
        {
            memoryCache.Set(cacheKey, prodRepo.Products);
            return prods;
        }
    }
}

1 Ответ

0 голосов
/ 11 октября 2018

Прежде всего, чтобы уточнить, статический класс не может быть создан, так как вы можете внедрить экземпляры в его конструктор, используя среду внедрения зависимостей.Дело не в том, что статические классы плохо работают с DI, они вообще не работают и не имеют никакого смысла в контексте внедрения зависимостей.

Вашему контроллеру необходим CachingEngine, поэтому вам нужно внедрить его,простое правило настройки DI в вашем программном обеспечении: не используйте оператор new.

Каждый раз, когда вы используете оператор new, вы тесно связываете свой код с определенным типом, и у вас возникает именно та проблема,Dependency Inject пытается решить.

public class Startup
{

   public void ConfigureServices(IServiceCollection services)
   {

    //Add Dependencies
    services.AddTransient<IProductRepository, ProductRepository>();

    //configure DI for IMemoryCache and CachingEngine
    services.AddTransient<IMemoryCache, MyMemoryCacheClass>();
    services.AddTransient<MyICachingEngineInterface, CachingEngine>();

    //Extention method that sets up the shared objects used in MVC apps
    services.AddMvc();
    services.AddMemoryCache();
    ....
   }
}

public class MainController : Controller
{

    private readonly MyICachingEngineInterface _cachingEngine;

    public MainController(MyICachingEngineInterface cachingEngine)
    {

        _cachingEngine = cachingEngine;
    }

    public IActionResult Index()
    {
        var products = _cachingEngine.GetProducts();
        ....
    }
}
...