У меня странная проблема с использованием ASP. NET в сочетании с Entity Framework и Unity Container.
Эта проблема only возникает после запуска приложения от нескольких часов до нескольких дней. И после этого происходит временное исправление (снова на тот же период) путем перезапуска IIS.
Иногда проблема дает исключение при попытке ввести (используя unity-container) Контроллер.
Пример:
public class PersonController
{
private readonly ICrudService<Person> personCrudservice;
public PersonController(ICrudService<Person> personCrudservice)
{
this.personCrudservice = personCrudservice;
}
}
Исключением здесь является: An error occurred when trying to create a controller of type 'PersonController'. Make sure that the controller has a parameterless public constructor.
Конечно, контроллер не имеет конструктора без параметров, но использует контейнер-единство personCrudservice вводится Однако этого не происходит, поскольку метод dbContext.Set<Person>()
дает следующее исключение: An item with the same key has already been added.
, что приводит к исключению, показанному выше.
Другим примером является исключение при попытке загрузить данные из базы данных. Что дает исключение NullReference. (Опять же, не все время и данные существуют в базе данных)
Можете ли вы, ребята, помочь мне решить проблему?
DataContext.cs :
public class DataContext : IUnitOfWork, IRepositoryFactory, ICrudServiceFactory
{
private const string CONNECTIONSTRING = "Constring";
private static readonly MedicijnverstrekkingDbContext dbContext = new MedicijnverstrekkingDbContext(CONNECTIONSTRING);
public DbContext DbContext => dbContext;
public static volatile Dictionary<string, object> repositories = new Dictionary<string, object>();
public DataContext()
{
dbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false;
}
public void SaveChanges()
{
dbContext.SaveChanges();
}
public void Dispose()
{
dbContext.Dispose();
}
public IRepository<T> CreateRepositoryFor<T>() where T : class, IEntity
{
var naam = typeof(T).FullName;
var repos = default(IRepository<T>);
if(repositories.ContainsKey(naam))
{
repos = repositories[naam] as IRepository<T>;
}
if(repos == null)
{
repos = new Repository<T>(dbContext.Set<T>());
repositories[naam] = repos;
}
return repos;
}
ICrudService<T> ICrudServiceFactory.GenerateCrudServiceFor<T>(IUnityContainer unityContainer)
{
var icrudServiceType = typeof(ICrudService<T>);
var tService = icrudServiceType.Assembly.GetTypes().Where(t => icrudServiceType.IsAssignableFrom(t)).FirstOrDefault();
//If predefined crud service exists, create an instance, otherwise create a generic crud service.
if (tService != null)
{
return (ICrudService<T>)Activator.CreateInstance(tService, new object[] { unityContainer.Resolve<IUnitOfWork>(), unityContainer.Resolve<IRepository<T>>() });
}
else
{
return new GenericCrudService<T>(unityContainer.Resolve<IUnitOfWork>(), unityContainer.Resolve<IRepository<T>>());
}
}
}
UnityConfig.cs
public class UnityConfig
{
private static readonly Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
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);
RegisterAuthenticationDependencies(unityContainer);
}
private static void RegisterDataContextAndUnitOfWork(IUnityContainer container)
{
container.RegisterType<IUnitOfWork, DataContext>(HttpContextLifetimeManager.FromType<DataContext>());
container.RegisterType<IRepositoryFactory, DataContext>(HttpContextLifetimeManager.FromType<DataContext>());
container.RegisterType<ICrudServiceFactory, DataContext>(HttpContextLifetimeManager.FromType<DataContext>());
}
private static void RegisterAuthenticationDependencies(IUnityContainer container)
{
container.RegisterType<IUserStore<GebruikerModel>, UserStore>(HttpContextLifetimeManager.FromType<UserStore>());
container.RegisterType<IRoleStore<RoleModel, string>, RoleStore>(HttpContextLifetimeManager.FromType<RoleStore>());
container.RegisterFactory<UserManager<GebruikerModel>>(unityContainer =>
{
var userStore = unityContainer.Resolve<IUserStore<GebruikerModel>>();
var manager = new UserManager<GebruikerModel>(userStore)
{
PasswordHasher = new BcryptPasswordHasher()
};
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<GebruikerModel>
{
MessageFormat = "Uw inlogcode is {0}."
});
manager.SmsService = new SmsService();
return manager;
});
container.RegisterType<ICurrentUserProvider, CurrentHttpUserProvider>();
}
private static void RegisterRepositories(IUnityContainer container)
{
var registerRepositoryMethodName = MemberNameHelper.GetActionName(() => RegisterRepository<IEntity>(container));
var registerCrudserviceName = MemberNameHelper.GetActionName(() => RegisterCrudService<IEntity>(container));
var registerRepositoryMethodInfo = typeof(UnityConfig).GetMethod(registerRepositoryMethodName, BindingFlags.NonPublic | BindingFlags.Static);
var registerCrudserviceMethodInfo = typeof(UnityConfig).GetMethod(registerCrudserviceName, BindingFlags.NonPublic | BindingFlags.Static);
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 });
var registerCrudserviceMethod = registerCrudserviceMethodInfo.MakeGenericMethod(entityType);
registerCrudserviceMethod.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>(),
HttpContextFactoryLifetimeManager.ForRepository<T>()
);
}
private static void RegisterCrudService<T>(IUnityContainer unityContainer) where T : class, IEntity
{
unityContainer.RegisterFactory<ICrudService<T>>(
factory => factory.Resolve<ICrudServiceFactory>().GenerateCrudServiceFor<T>(factory),
HttpContextFactoryLifetimeManager.ForCrudService<T>()
);
}
}
У меня есть эта проблема уже несколько недель, и я пробовал разные LifeTimeManager, а также понижал Unity-Container / Entity Framework Помогите.
Stacktrace: элемент с таким же ключом уже добавлен.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Entity.Internal.InternalContext.Set[TEntity]()
at System.Data.Entity.DbContext.Set[TEntity]()
at Multitask.COMPANYNAME.DataAccess.EntityFramework.DataContext.CreateRepositoryFor[T]() in C:\Source\Workspaces\Multitask.COMPANYNAME\Multitask.COMPANYNAME\DataAccess\DataContext.cs:line 50
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Multitask.COMPANYNAME.WebApplication.Unity.HttpContextFactoryLifetimeManager.GetValue(ILifetimeContainer container) in C:\Source\Workspaces\Multitask.COMPANYNAME\Multitask.COMPANYNAME\WebApplication\Unity\HttpContextFactoryLifetimeManager.cs:line 60
at Unity.Strategies.LifetimeStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.<>c.<.ctor>b__73_1(BuilderContext& context)
at Unity.UnityContainer.Unity.IUnityContainer.Resolve(Type type, String name, ResolverOverride[] overrides)
at Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides)
at Multitask.COMPANYNAME.DataAccess.EntityFramework.DataContext.Multitask.COMPANYNAME.Service.DataAccess.ICrudServiceFactory.GenerateCrudServiceFor[T](IUnityContainer unityContainer) in C:\Source\Workspaces\Multitask.COMPANYNAME\Multitask.COMPANYNAME\DataAccess\DataContext.cs:line 131
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Multitask.COMPANYNAME.WebApplication.Unity.HttpContextFactoryLifetimeManager.GetValue(ILifetimeContainer container) in C:\Source\Workspaces\Multitask.COMPANYNAME\Multitask.COMPANYNAME\WebApplication\Unity\HttpContextFactoryLifetimeManager.cs:line 70
at Unity.Strategies.LifetimeStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.<>c.<.ctor>b__73_2(BuilderStrategy[] chain, BuilderContext& context)
at Unity.Builder.BuilderContext.Resolve(Type type, String name, InternalRegistration registration)
at Unity.Builder.BuilderContext.Resolve(Type type, String name)
at Unity.Builder.BuilderContext.Resolve(ParameterInfo parameter, Object value)
at Unity.Processors.ConstructorProcessor.<>c__DisplayClass16_0.<GetResolverDelegate>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Strategies.BuildPlanStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.<>c.<.ctor>b__73_2(BuilderStrategy[] chain, BuilderContext& context)
at Unity.Builder.BuilderContext.Resolve(Type type, String name, InternalRegistration registration)
at Unity.Builder.BuilderContext.Resolve(Type type, String name)
at Unity.Builder.BuilderContext.Resolve(ParameterInfo parameter, Object value)
at Unity.Processors.ConstructorProcessor.<>c__DisplayClass16_0.<GetResolverDelegate>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Strategies.BuildPlanStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.<>c.<.ctor>b__73_1(BuilderContext& context)
at Unity.UnityContainer.Unity.IUnityContainer.Resolve(Type type, String name, ResolverOverride[] overrides)
at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
--- End of inner exception stack trace ---
at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)````