我仅将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;
}
}
}
答案 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();
....
}
}