L'unité DI Injecter DbContext avec PerRequestLifetimeManager
J'ai le code suivant qui initialiser les instances de l'Unité:
IUnityContainer container = new UnityContainer();
container.RegisterType<DbContext, VotingSystemContext>(new PerRequestLifetimeManager(), new InjectionConstructor());
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>));
container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager());
container.RegisterTypes(
AllClasses.FromAssemblies(
Assembly.GetAssembly(typeof(IUserService)),
Assembly.GetAssembly(typeof(UserService))),
WithMappings.FromMatchingInterface,
WithName.Default, WithLifetime.PerResolve);
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
- Je utiliser PerRequestLifetimeManager
j'ai donc suivi la suggestion sur MSDN et d'ajouter une nouvelle ligne à la fin du code ci-dessus:
DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
Mais après je l'ai placé. Lorsque la page(uniquement en html statique) est chargé j'ai envoyer une requête ajax à mon WebApi constroller que les appels GenericReposirory
Get()
méthode que jeter de l'erreur: The operation cannot be completed because the DbContext has been disposed.
Sans cette ligne de code, tout fonctionne OK, mais sans le définir, probablement, le contexte ne sera pas en disposer.
Mon UnitOfWork
classe:
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly VotingSystemContext _context;
private bool _disposed;
//GenericRepository properties
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
P. S. j'utilise la dernière version de l'Unité 3.5.1404.
Merci à l'avance.
EDIT:
Méthode Get() de Dépôt:
public sealed class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : BaseEntity
{
public GenericRepository(VotingSystemContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
private readonly DbSet<TEntity> _dbSet;
private readonly VotingSystemContext _context;
public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "", int? page = null, int? pageSize = null)
{
IQueryable<TEntity> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
List<string> properties = includeProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
properties.ForEach(property =>
{
query = query.Include(property);
});
if (orderBy != null)
{
query = orderBy(query);
}
if (page != null && pageSize != null)
{
query = query.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value);
}
return query;
}
//other methods like Delete, Update and GetById
}
}
ApiController de Get()
méthode:
public IEnumerable<VotingModel> Get(int page = 1, int size = 10)
{
//get all themes
List<Theme> themes = _themeService.GetAll(page, size);
//convert themes to VotingModel (same model as Theme just without converting system throw an error about serializing object and also add new filed UserName).
List<VotingModel> model = themes.Select(t =>
{
MembershipUser membershipUser = Membership.GetUser(t.UserId ?? -1);
return t.ToVotingModel(membershipUser != null ? membershipUser.UserName : string.Empty);
}).ToList();
return model;
}
Service GetAll()
méthode:
public List<Theme> GetAll(int page = 1, int pageSize = 10)
{
return UnitOfWork.ThemeRepository.Get(null, null, "Comments", page, pageSize).ToList();
}
- Voir votre référentiel
Get()
code peut aider, ainsi que votre contrôleur. - bonjour, j'ai ajouté des informations supplémentaires.
- J'utilise ce type de soution: thorarin.net/blog/post/2013/02/12/....
- Je ne vois pas le constructeur(s) pour le
UnitOfWork
classe. A-t-elle unDbContext
injecter? Aussi, le service ont unUnitOfWork
injecter? La chaîne semble un peu bancale ici sans plus d'info. - pour les deux questions, la réponse est oui.
Vous devez vous connecter pour publier un commentaire.
Je voudrais donc avoir de la structure de dépendance de la sorte:
et vous coller avec l'Unité de la manipulation de la durée de vie de chacun. La chose est cependant, vous voulez les Services à la demande de la portée, tout comme les autres (UoW et de Repos). Vous pouvez avoir la durée de vie en service configurer de cette façon, mais je ne sais pas l'Unité sur le dessus de ma tête. Je vois que vous avez l'UofW et de repos ensemble avec la demande de la durée de vie.
La grande différence étant que le
UnitOfWork
n'ont pas de dépendance sur les référentiels, mais plutôt l'inverse. Ainsi, le référentiel de la classe de base obtient sonDbSet<T>
via leUnitOfWork
qui a leDbContext.
Vous auriez un peu de méthode, surUnitOfWork
qui retourne unIDbSet<T>
comme si vous appeliez que sur leDbContext.
LaUnitOfWork
être un wrapper pourDbContext
ce qui en soi est assez Unité de Travail-comme.La
UnitOfWork
serait similaire, mais de prendre de laDbContext
comme la dépendance (vous pouvez déjà avoir ce mais omis le constructeur):Le service aurait le référentiel injecté:
La
ApiController
serait d'obtenir les services nécessaires injecté, dans ce cas, leThemeService
:L'idée ultime étant que l'Unité de conteneur gère la durée de vie de toutes les dépendances et le
UnitOfWork
n'a pas à essayer de gérer vos dépôts. Votre lignerester et le
DbContext
serait d'obtenir l'élimination par l'Unité, et vous n'avez pas à appelerDispose()
sur vous-même.IUnitOfWork
dans le constructeur.IDisposable
avec sesDispose
méthode, mais le problème persiste.Essayez d'utiliser Microsoft.Les pratiques.De l'unité.HierarchicalLifetimeManager au lieu de cela, c'est moyen:
L'instar de l'article: https://jasenhk.wordpress.com/2013/06/11/unit-of-work-and-repository-pattern-with-unity-dependency-injection/