Base solution for your next web application
Open Closed

Dependency Injection of AuthorizationProvider #271


User avatar
0
waku created

Hi, I need to use the RoleManager in my AuthorizationProvider like this:

public class UserPermissionProvider : AuthorizationProvider
    {
        private readonly RoleManager _roleManager;

        public UserPermissionProvider(RoleManager roleManager)
        {
            _roleManager = roleManager;
        }
    }

My app runs well as I expected, but when I run unit tests, all the tests failed. Here's the error message:

System.TypeInitializationException“Effort.DbConnectionFactory”的类型初始值设定项引发异常。 在 Effort.DbConnectionFactory.CreateTransient() 在 Castle.MicroKernel.ComponentActivator.FactoryMethodActivator1.Instantiate(CreationContext context) 在 Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) 在 Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) 在 Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) 在 Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) 在 Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, ref Burden burden) 在 Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired) 在 Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) 在 Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) 在 Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) 在 Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) 在 Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) 在 Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) 在 Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally) 在 Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) 在 Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, ref Burden burden) 在 Castle.MicroKernel.Handlers.ExtendedHandler.InvokeResolvePipeline(Int32 extensionIndex, ResolveInvocation invocation) 在 Castle.MicroKernel.Handlers.ComponentLifecycleExtension.Intercept(ResolveInvocation invocation) 在 Castle.MicroKernel.Handlers.ExtendedHandler.InvokeResolvePipeline(Int32 extensionIndex, ResolveInvocation invocation) 在 Castle.MicroKernel.Handlers.ExtendedHandler.Resolve(CreationContext context, Boolean instanceRequired) 在 Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) 在 Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) 在 Castle.Windsor.WindsorContainer.Resolve() 在 BMS.Tests.BMSTestBase.UsingDbContext(Action1 action) 位置 BMSTestBase.cs: line 49 在 BMS.Tests.BMSTestBase..ctor() 位置 BMSTestBase.cs: line 32 在 BMS.Tests.Users.RoleAppServiceTests..ctor() 位置 RoleAppServiceTests.cs: line 11 Effort.Exceptions.EffortExceptionThe Effort library failed to register its provider automatically, so manual registration is required.

a) Call the Effort.Provider.EffortProviderConfiguration.RegisterProvider() method at entry point of the application

or

b) Add the following configuration to the App.config file: <system.data> <DbProviderFactories> <add name="Effort.Provider" > invariant="Effort.Provider" description="Effort.Provider" type="Effort.Provider.EffortProviderFactory, Effort" /> </DbProviderFactories> </system.data>

<entityFramework> <providers> <provider invariantName="Effort.Provider" > type="Effort.Provider.EffortProviderServices, Effort" /> </providers> </entityFramework> 在 Effort.Provider.EffortProviderConfiguration.RegisterDbConfigurationEventHandler() 在 Effort.Provider.EffortProviderConfiguration.RegisterProvider() 在 Effort.DbConnectionFactory..cctor() System.InvalidOperationExceptionThe Entity Framework was already using a DbConfiguration instance before an attempt was made to add an 'Loaded' event handler. 'Loaded' event handlers can only be added as part of application start up before the Entity Framework is used. See <a class="postlink" href="http://go.microsoft.com/fwlink/?LinkId=260883">http://go.microsoft.com/fwlink/?LinkId=260883</a> for more information. 在 System.Data.Entity.Infrastructure.DependencyResolution.DbConfigurationManager.AddLoadedHandler(EventHandler`1 handler) 在 Effort.Provider.EffortProviderConfiguration.RegisterDbConfigurationEventHandler()

(sorry for the Chinese...)

It seems that unit tests can not inject the RoleManager to my AuthorizationProvider, how to solve it?


4 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    That's related to EffortDB initialization, not arelated to injection. I got this exception before.

    Go to ParentIf you have used Database.SetInitializer... method in somewhere in your code, it causes that problem. Remove it (at least for tests) and try again.

  • User Avatar
    0
    waku created

    <cite>hikalkan: </cite> Hi,

    That's related to EffortDB initialization, not arelated to injection. I got this exception before.

    Go to ParentIf you have used Database.SetInitializer... method in somewhere in your code, it causes that problem. Remove it (at least for tests) and try again.

    Sorry, but I don't use Database.SetInitializer method, I use the generated code by template to seed my data, they'are very "standard":

    InitialDataBuilder:

    public class InitialDataBuilder
        {
            private readonly BMSDbContext _context;
    
            public InitialDataBuilder(BMSDbContext context)
            {
                _context = context;
            }
    
            public void Build()
            {
                new DefaultTenantRoleAndUserBuilder(_context).Build();
            }
        }
    

    BMSTestBase:

    public abstract class BMSTestBase : AbpIntegratedTestBase
        {
            protected BMSTestBase()
            {
                //Fake DbConnection using Effort!
                LocalIocManager.IocContainer.Register(
                    Component.For<DbConnection>()
                        .UsingFactoryMethod(Effort.DbConnectionFactory.CreateTransient)
                        .LifestyleSingleton()
                    );
    
                //Seed initial data
                UsingDbContext(context => new InitialDataBuilder(context).Build());
    
                LoginAsDefaultTenantAdmin();
            }
    

    Also, I do need the seed data to run my unit tests, so I can't remove them. Maybe I didn't understand your solution, but could you explain more? Thank you!

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    You can try this: Download the sample application which includes working unit tests (<a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/SimpleTaskSystem">https://github.com/aspnetboilerplate/as ... TaskSystem</a>) and compare with yours. Maybe your test project's app.config does not contain proper EF configuration.

  • User Avatar
    0
    waku created

    <cite>hikalkan: </cite> Hi,

    You can try this: Download the sample application which includes working unit tests (<a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/SimpleTaskSystem">https://github.com/aspnetboilerplate/as ... TaskSystem</a>) and compare with yours. Maybe your test project's app.config does not contain proper EF configuration.

    I changed my app.config, it didn't work either. :cry: What makes me think it's related to dependency injection is that if I remove the RoleManager parameter from my AuthorizationProvider's constructor, then my unit tests are OK.