How to access repository from IRouter

I'm developing modular application and I'd like for entities from different modules to be able to register their own friendly url slugs.

app.UseMvc(routes =>
{
    routes.Routes.Add(new SlugRouter(routes.DefaultHandler));
    (...)
});

But following code throws Cannot access a disposed object. Object name: 'CommerceDbContext'. when trying to access slug from the repository.

public class SlugRouter : IRouter
{
    private readonly IRouter _target;

    public SlugRouter(IRouter target)
    {
        _target = target;
    }

    public async Task RouteAsync(RouteContext context)
    {
        var slugRepository = context.HttpContext.RequestServices.GetService<IRepository<SlugEntity>>();

        // ERROR: Cannot access a disposed object. Object name: 'CommerceDbContext'
        var urlSlug = await slugRepository.GetAllIncluding(x => x.EntityType).FirstOrDefaultAsync(x => x.Slug == context.HttpContext.Request.Path.Value);
        (...)
    }       

It must be something simple I'm missing to be able to access the repository from router. Thanks for any help.

2 answers

  • answered 2018-01-16 14:57 aaron

    Begin a unit of work:

    public async Task RouteAsync(RouteContext context)
    {
        var slugRepository = context.HttpContext.RequestServices.GetService<IRepository<SlugEntity>>();
        var unitOfWorkManager = context.HttpContext.RequestServices.GetService<IUnitOfWorkManager>();
    
        using (var uow = unitOfWorkManager.Begin())
        {
            var urlSlug = await slugRepository.GetAllIncluding(x => x.EntityType).FirstOrDefaultAsync(x => x.Slug == context.HttpContext.Request.Path.Value);
            await uow.CompleteAsync();
        }
    }
    

  • answered 2018-01-16 14:57 Roman Pokrovskij

    Access IModel. You do not need dbContext for.

    for entities from different modules to be able to register their own friendly url slugs

    I do it this way:

    1) move OnModelCreating to static methiod

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            BuildModel(modelBuilder);
        }
    
        public static void BuildModel(ModelBuilder modelBuilder)
        {
            // ...
        }
    

    2) Create model where you need:

            var conventionSet = new ConventionSet();
            var modelBuilder = new ModelBuilder(conventionSet);
            AdminkaDbContext.BuildModel(modelBuilder);
            var mutableModel = modelBuilder.Model; 
    

    There is your meta (in mutableModel ). You can loop through entities (types of entities).