如何在.NET Core MVC中的控制器外部进行缓存和依赖注入

时间:2018-10-10 21:52:13

标签: c# asp.net asp.net-core dependency-injection asp.net-core-mvc

我仅将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 :(得分:2)

首先要澄清的是,静态类无法实例化,因此如何使用依赖项注入框架将实例化实例注入其构造函数中。并不是静态类不适用于DI,它们根本不起作用,并且在依赖注入的情况下毫无意义。

您的控制器需要一个CachingEngine,因此您需要注入它,这是在软件中设置DI的简单规则:请勿使用new运算符。

每次使用new运算符时,您都将代码紧密耦合到特定类型,并且遇到了依赖注入试图解决的确切问题。

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