ʞᴉɯ*_*ʞᴉɯ 5 c# asp.net-mvc dependency-injection asp.net-core
在一个asp.net核心mvc项目中,我有一个ViewModel用于布局的抽象类,它需要一些属性才能正常运行,而每个具体页面的ViewModel派生结果都来自于此:
public abstract class Layout
{
// required to function properly
public string Prop1 { get; set; }
// required to function properly
public IEnumerable<Foo> FooList { get; set; }
protected Layout()
{
// Populate FooList from an util caching class?
}
}
public class ViewModelHome : Layout {}
public class ViewModelProducts : Layout {}
Run Code Online (Sandbox Code Playgroud)
布局需要FooList从数据库或缓存填充的,因为它是不经常更改的数据。
我想避免将每个必填字段放在构造函数中,以使其不太冗长,并且我想避免对每个派生类进行以下操作:
var model = new ViewModelHome();
model.FooList = .....
Run Code Online (Sandbox Code Playgroud)
在asp.net中IMemoryCache,可以通过DI的来进行核心缓存,所以我不能这样写:
public abstract class Layout
{
protected Layout()
{
var cacheClass = new MyCacheClass(...IMemoryCache??...);
this.FooList = cacheClass.GetFooList();
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为我是Layout在服务中自己创建的,而服务又是从控制器调用的。
public class MainController : Controller
{
private readonly IMainService _service;
public MainController(IMainService service)
{
_service = service;
}
public IActionResult Home()
{
return View(_service.GetHomeViewModel());
}
public IActionResult Products()
{
return View(_service.GetProductsViewModel());
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:我应该在抽象类构造函数中放入从数据库或缓存中获取数据的逻辑吗?
谢谢
我想你这里有几个选择:
IMemoryCache通过 DI 将您的属性注入到属性中(大多数容器都支持它),我不推荐这种方法。public class Foo {
[Inject] // or other marker attribute specific to your IoC
public readonly IMemoryCache;
....
}
Run Code Online (Sandbox Code Playgroud)
public Foo(): base()
{
base.MemoryCache = IoC.Resolve<IMemoryCache>();
}
Run Code Online (Sandbox Code Playgroud)
public Foo(IMemoryCache cache): base(cache)
Run Code Online (Sandbox Code Playgroud)
public void Foo(IMemoryCache cache, int bar)
Run Code Online (Sandbox Code Playgroud)
public Foo(IBar bar, IBaz baz, IContainer container): base(container)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我曾遇到过在大量重构过程中选项 5 效果最好的情况。