Я работаю над обновлением проектов одной из своих компаний до более новых версий MVC, Entity Framework и Unity. Большая часть работы была завершена, однако, у меня есть эта проблема при загрузке данных из базы данных. Это не происходит при каждом запросе, и большинство приложений работает нормально. Проблема возникает при вызовах API, выполняемых приложением при наличии нескольких одновременных вызовов.
Я пытался переключить LifeTimeManager контейнеров Unity на разные типы с разными результатами (ни один из них на самом деле не решил проблему).
Это мой класс DataContext
public class DataContext : IUnitOfWork, IRepositoryFactory
{
private const string CONSTRING = "CONSTRING";
private static volatile DbContext dbContext = new DbContext(CONSTRING);
private static volatile ConcurrentBag<object> repositories = new ConcurrentBag<object>();
public DbContext DbContext => dbContext;
public DataContext()
{
Database.SetInitializer<DbContext>(null);
}
public void SaveChanges()
{
dbContext.SaveChanges();
}
public void Dispose()
{
dbContext.Dispose();
}
public IRepository<T> CreateRepositoryFor<T>() where T : class, IEntity
{
var reposType = typeof(Repository<T>);
var repos = (IRepository<T>)repositories.FirstOrDefault(r => r.GetType() == reposType);
if (repos == null)
{
repos = new Repository<T>(dbContext.Set<T>());
repositories.Add(repos);
}
return repos;
}
}
Это мой UnityConfig
public class UnityConfig
{
#region Unity Container
private static readonly Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Configured Unity Container.
/// </summary>
public static IUnityContainer Container => container.Value;
#endregion
public static void RegisterTypes(IUnityContainer container)
{
RegisterDependencies(container);
System.Web.Mvc.DependencyResolver.SetResolver(new UnityDependencyResolverAdapter(container));
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
private static void RegisterDependencies(IUnityContainer unityContainer)
{
RegisterDataContextAndUnitOfWork(unityContainer);
RegisterRepositories(unityContainer);
}
private static void RegisterDataContextAndUnitOfWork(IUnityContainer container)
{
container.RegisterType<IUnitOfWork, DataContext>(new ContainerControlledLifetimeManager());
container.RegisterType<IRepositoryFactory, DataContext>(new ContainerControlledLifetimeManager());
container.RegisterType<IChangeTracker, DataContext>(new ContainerControlledLifetimeManager());
container.RegisterType(typeof (ICrudService<>), typeof (GenericCrudService<>));
}
private static void RegisterRepositories(IUnityContainer container)
{
// Haal MethodInfo op zodat we at runtime de static RegisterRepository<T> kunnen aanroepen
var registerRepositoryMethodName = MemberNameHelper.GetActionName(() => RegisterRepository<IEntity>(container));
var registerRepositoryMethodInfo = typeof(UnityConfig).GetMethod(registerRepositoryMethodName, BindingFlags.NonPublic | BindingFlags.Static);
// Registreer een repository voor iedere IEntity class in Domain project
foreach (var entityType in typeof(IEntity).Assembly.GetTypes().Where(t => typeof(IEntity).IsAssignableFrom(t)))
{
var registerRepositoryMethod = registerRepositoryMethodInfo.MakeGenericMethod(entityType);
registerRepositoryMethod.Invoke(null, new object[] { container });
}
}
private static void RegisterRepository<T>(IUnityContainer unityContainer) where T : class, IEntity
{
unityContainer.RegisterFactory<IRepository<T>>(
factory => factory.Resolve<IRepositoryFactory>().CreateRepositoryFor<T>(),
new ContainerControlledLifetimeManager()
);
}
}
Строка подключения: Data Source=LOCALHOST;Initial Catalog=Database;Integrated Security=true;MultipleActiveResultSets=True
Сообщение об ошибке: The underlying provider failed on Open.