我们的配置是使用AutoFac的MVC5 C#应用程序.
我们有很多单例,如果它们是在第一个请求中初始化的,那么它们会对用户造成不良的体验,因为它们的初始化总共需要3-4秒左右的时间.我们正在使用AutoFac进行依赖注入,我想知道是否有任何方法可以确保在App_Start上构建单例(或这些特定的单例),这样我们就不会在用户发送第一个请求时浪费时间吗?如果不是,解决此问题的最佳方法是什么?
解决方法:
解决此类问题的一般方法是在代理实现后隐藏此类重量较大的对象.这样,您可以在应用程序启动时直接触发初始化过程,而该操作在后台运行,而不会阻止任何请求(除非他们在请求期间需要未初始化的数据).
如果您的代码如下所示:
// The abstraction in question
public interface IMyService
{
ServiceData GetData();
}
// The heavy implementation
public class HeavyInitializationService : IMyServic {
public HeavyInitializationService() {
// Load data here
Thread.Sleep(3000);
}
public ServiceData GetData() => ...
}
可以如下创建代理:
public class LazyMyServiceProxy : IMyService {
private readonly Lazy<IMyService> lazyService;
public LazyMyServiceProxy(Lazy<IMyService> lazyService) {
this.lazyService = lazyService;
}
public ServiceData GetData() => this.lazyService.Value.GetData();
}
您可以按以下方式使用此代理:
Lazy<IMyService> lazyService = new Lazy<IMyService>(() =>
new HeavyInitializationService());
container.Register<IMyService>(c => new LazyMyServiceProxy(lazyService))
.SingleInstance();
// Trigger the creation of the heavy data on a background thread:
Task.Factory.StartNew(() => {
// Triggers the creation of HeavyInitializationService on background thread.
var v = lazyService.Value;
});