Autofac: No Scope with a Tag matching Autofacwebrequest

Asked

Viewed 41 times

0

I would like your help to solve the following problem: Imagine that I have a Servicefactory class responsible for creating services (such as srvFact.Create<MyService>()), a Repositoryfactory class responsible for creating repositories (such as repFact.Create<MeuRepositorio>()). Such classes have dependencies, which I will demonstrate through the symbol A <= B, which denotes that A depends on B. For my case I have to: ServiceFactory <= RepositoryFactory.
RepositoryFactory <= DbContext.
That said, imagine that my api uses Automapper to map Viewmodels in Entity Framework Objects and that for certain mappings, it is necessary to access some repository.
What I want: I would like that given a request, as long as that request lives, any request to a Dbcontext instance, return to the same instance, to better control the Dbcontext cycle of activity. Let’s go to the code snippet:

internal void Configure(ContainerBuilder builder)
{
    ConfigureContainer(builder);
    Container = builder.Build();
    RegisterMapping();
}

private void ConfigureContainer(ContainerBuilder builder)
{
    var dbContextType = GetDbContextType();
    var assembly = GetWebApiAssembly();

    // (a) com essa linha o metodo 'RegisterMapping' não consegue resolver a instancia de ServiceFactory
    builder.RegisterType(dbContextType).As(typeof(DbContext)).InstancePerRequest();

    // (b) COM ESSA LINHA, O METODO 'RegisterMapping' consegue obter uma instancia de ServiceFactory
    //builder.RegisterType(dbContextType).As(typeof(DbContext)).InstancePerRequest("myrequest");

    builder.RegisterType<RepositoryFactory>().As<IRepositoryFactory>();
    builder.RegisterType<ServiceFactory>().As<IServiceFactory>();
    builder.RegisterApiControllers(assembly);
}

private void RegisterMapping()
{
    // usando (a) no metodo 'ConfigureContainer' temos um erro:
    // 'No scope with a Tag matching AutofacWebRequest'
    var serviceFactory = Container.Resolve<IServiceFactory>();
    Mapper.Initialize(cfg => ConfigureMapping(cfg, serviceFactory));

    // usando (b) no metodo 'ConfigureContainer' conseguimos resolver ServiceFactory, porém é injetado instancias diferentes de DbContext
    // o que faz com que o mapeamento dentro de 'ConfigureMapping' gere o erro: 
    // 'An entity object cannot be referenced by multiple instances of IEntityChangeTracker'
    //using (var scope = Container.BeginLifetimeScope("myrequest"))
    //{
    //    var serviceFactory = scope.Resolve<IServiceFactory>();
    //    Mapper.Initialize(cfg => ConfigureMapping(cfg, serviceFactory));
    //}
}

The Method Configure(new ContainerBuilder()) is called in Global.asax: DbAccessWrapper.Init(new VaiQueConfig()); where the builder new VaiQueConfig() calls the method Configure passing an instance of ContainerBuilder

  • sorry.. I couldn’t understand what you want and what your problem is. are you giving any error? or want to "improve" the way utiliza injeção de dependência?

  • I’m having problems, the first is that var serviceFactory = scope.Resolve<IServiceFactory>() generates an error (No Scope with a Tag matching Autofacwebrequest ) if configuring the container with the line builder.RegisterType(dbContextType).As(typeof(DbContext)).InstancePerRequest();

  • The second is that if I use the line builder.RegisterType(dbContextType).As(typeof(DbContext)).InstancePerRequest("myrequest") i can obtain the instance of Servicefactory, but the dependency (Repositoryfactory) injected in Servicefactory is injected with a new instance of Dbcontext, since Repositoryfactory has as dependency Dbcontext, and this generates the error (An Entity Object cannot be referenced by Multiple instances of Ientitychangetracker) when using the service in the mapping layer

  • Come on, somebody?

  • Hard this case of yours, as I do not know what it is, I will comment.. if it works I answer, you already tried to do so builder.RegisterType<SeuDbContext>().As<DbContext>(); to inject the context?

  • Yes, I will post the repository link, in case you want to simulate to understand. in general I want to build a plugin that cruds Generico, already mapping viewmodels in dto, but for that, I need a context instance only Entity by request to avoid multiple contexts errors, or errors when mult thread when context is Singleton Repository: https://github.com/Jass91/WebApiLink

  • Sorry, actually I can not use as you said, because I need to dynamically get the kind of class that inherits from Dbcontext, because each person could have one. ex: Meudbctx1, Odbctxdele and etc...

Show 2 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.