vNext. AspNet.Identity and custom UserStore. UserStore disposed exception - asp.net-mvc

I'm trying to understand vNext.
I wrote custom UserStore, that works with MongoDB and implements these interfaces:
public class UserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>,
IUserLoginStore<ApplicationUser>, IUserClaimStore<ApplicationUser>, IUserEmailStore<ApplicationUser>, IUserRoleStore<ApplicationUser>,
IUserTwoFactorStore<ApplicationUser>
In Startup.cs added:
app.UseServices(services =>
{
services.AddIdentity<ApplicationUser>()
.AddUserStore(() => { return new UserStore(); })
.AddUserManager<UserManager<ApplicationUser>>()
.AddHttpSignIn();
services.AddMvc();
});
Then tried to use unchanged AccountController from Visual Studio template and have troubles.
When signing in i getting ObjectDisposedException in UserStore.FindByNameAsync() -- something called UserStore.Dispose().
In UserManager code on github.com/aspnet Store.Dispose() called only in UserManager.Dispose().
I can just ignore calls of Dispose and all works fine, but this is not good way.
So i have no ideas what shall i do
P.S. The Question is: what (and why) can call UserStore.Dispose()?

In vNext, DI is built in and manages the lifetime of the identity services. You are probably trying to use identity after the services have been disposed, by default identity services have lifetimes scoped to a request, so if for example, you are trying to hang onto a reference to a user manager and reuse it across multiple requests, that would cause the ObjectDisposedException.

Related

ASP.net Core EF DataContext not Scoped as per Documentation?

In my Startup.cs file, I have set up a data context to participate in DI.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlServer("Connection String");
});
}
According to Dependency Injection Doc, the above code automatically puts the data context as Scoped in the IoC container. I am under the impression that an instance of MyDbContext is created for every request. A subsequent request would then have a new MyDbContext instance throughout its lifetime.
I have a controller set up and I'm passing MyDbContext via constructor DI. I make a simple GET request, and I get the data I want. I make a change to that very entity in SQL Management Studio, like change the value of one property/column. I make that same GET request. I don't get the new value that I set in SQL Management Studio.
This makes me think that ASP.net Core holds on to the same instance of MyDbContext across the lifetime of my application. If I stopped and restarted the application, that GET request will return the value I expected.
How do I refresh this data context for each request if I set it up with DI?
Am I missing something? I might post more code if needed.

Configuration(IAppBuilder) not firing on start up

The configuration method below doesn't get fired.
using Microsoft.Owin;
using Owin;
[assembly: OwinStartupAttribute(typeof(SCM.Web.Startup))]
namespace SCM.Web
{
public partial class Startup
{
public void Configuration(IAppBuilder builder) { }
}
}
I've followed all the hints from here and it's a new project, not an upgrade. I can't for my life see how to get it to stop on the breakpoint and I'm in need to get more suggestions on how to troubleshoot it.
It's an intranet application so there's no logging in. The identity gets set to the Windows credentials, instead. I need to assign the roles so that only certain users can access certain actions in the controllers. I'm usually applying OWIN and application cookies, so that's the method I'm trying to follow here, as well.
You need an OwinStartup attribute to tell Owin what method to call. From the docs:
Used to mark which class in an assembly should be used for automatic startup.
Add one to your project, before the namespace declaration:
[assembly: OwinStartup(typeof(Your.Namespace.Startup))]
namespace Your.Namespace
{
public partial class Startup
{
public void Configuration(IAppBuilder builder) { }
}
}
There are some other methods to let Owin know which method (described here) but this is the simplest and probably the most common.
If you are running the website on an external IIS or maybe on the "real" IIS installed on your computer (and not the one that is fired up when you start the run), then it's likely that you're missing the breakpoint because the debugger isn't attached to the process yet when you pass by.
I think that you can confirm it by either checking the settings of your solution and projects or simply adding this code to the method that you don't think that you pass through.
throw new Exception("Killroy was here...");

"An MVC filter provider has already been registered for a different Container instance." in Simple Injector 2.6

I previously had the setup for property injection in one of my attributes as
Container.RegisterInitializer<PermitAttribute>(initialize =>
{
initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
});
And the usage was
public class PermitAttribute : ActionFilterAttribute
{
public IQueryProcessor QueryProcessor { get; set; }
}
but after updating to simpleinjector 2.6.1 The property injection broke. When I am trying to access QueryProcessor object inside PermitAttribute. It resolves null value where as the Simple Injector configuration still has the same property injection via delegate instance .
Is there any breaking change in property injection behavior due to which it was working in v2.5 and its not working anymore in 2.6.1 ?
Update 1:
The Line in the configuration was throwing error for MVC filter provider registration for attributes in v2.6.1
container.RegisterMvcIntegratedFilterProvider();
For that I commented it . And it stopped the property injection working . The property injection was inside one of my attributes . I guess that's the line above which affects it. And its throwing error in v2.6.1
Update 2:
Message
An MVC filter provider has already been registered for a different
Container instance. Registering MVC filter providers for different
containers is not supported by this method.
StackTrace :
at SimpleInjector.SimpleInjectorMvcExtensions.RequiresFilterProviderNotRegistered(Container container)
at SimpleInjector.SimpleInjectorMvcExtensions.RegisterMvcIntegratedFilterProvider(Container container)
at RemsPortal.App_Start.SimpleInjectorInitializer.Initialize() in d:\Projects Work\RemsPortal\V2.0 Web Portal\RemsPortal\App_Start\SimpleInjectorInitializer.cs:line 39
Update 3 :
entire Configuration
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
container.RegisterMvcIntegratedFilterProvider();
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(Container Container)
{
Container.RegisterManyForOpenGeneric(typeof(IAsyncCommandHandler<,>),
AppDomain.CurrentDomain.GetAssemblies());
Container.RegisterOpenGeneric(typeof(ITransactionCommandHandler<,>),
typeof(TransactionCommandHandlerDecorator<,>));
Container.RegisterOpenGeneric(typeof(ICommandResult<>),
typeof(CommandHandlerResult<>));
Container.Register<ICommandResolver, CommandResolver>();
Container.Register<DbContext, RemsContext>();
Container.RegisterOpenGeneric(typeof(IPager<>), typeof(PagerModel<>));
//Container.RegisterPerWebRequest<DbContext, RemsContext>();
Container.Register<UserManager<Users, Guid>, RemsUserManager>();
Container.Register<RoleManager<Roles, Guid>, RemsRoleManager>();
Container.Register<IUserStore<Users, Guid>,
UserStore<Users, Roles, Guid, UserLogins, UserRoles, Claims>>();
Container.Register<IRoleStore<Roles, Guid>, RoleStore<Roles, Guid, UserRoles>>();
Container.RegisterManyForOpenGeneric(typeof(IAsyncQueryHandler<,>),
AppDomain.CurrentDomain.GetAssemblies());
Container.RegisterManyForOpenGeneric(typeof(IAsyncQueryHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
Container.RegisterManyForOpenGeneric(typeof(IQueryHandler<,>),
AppDomain.CurrentDomain.GetAssemblies());
Container.RegisterOpenGeneric(typeof(IQueryResult<>), typeof(QueryResult<>));
Container.RegisterOpenGeneric(typeof(IPaginator<>), typeof(Paginator<>));
Container.Register<IPaginator, Paginator>();
Container.RegisterOpenGeneric(typeof(IAsyncQueryHandler<>), typeof(BaseQuery<>));
Container.RegisterOpenGeneric(typeof(IQueryHandler<>), typeof(BaseQuery<>));
Container.Register<IQueryProcessor, QueryProcessor>(Lifestyle.Singleton);
Container.Register<ILog, NLogger>(Lifestyle.Singleton);
Container.RegisterInitializer<PermitAttribute>(initialize =>
{
initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
});
Container.RegisterInitializer<BaseController>(initialize =>
{
initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
initialize.Logger = Container.GetInstance<ILog>();
});
Container.RegisterInitializer<BaseCommandHandler>(initialize =>
{
initialize.UserManager = Container.GetInstance<RemsUserManager>();
initialize.RoleManager = Container.GetInstance<RemsRoleManager>();
initialize.RemsContext = Container.GetInstance<RemsContext>();
initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
});
Container.RegisterInitializer<BaseHandler>(initialize =>
{
initialize.UserManager = Container.GetInstance<RemsUserManager>();
initialize.RolesManager = Container.GetInstance<RemsRoleManager>();
});
}
The exception you are seeing is caused by a verification check that has been added to version 2.6 that prevents you from calling RegisterMvcAttributeFilterProvider and RegisterMvcIntegratedFilterProvider multiple times for different container instances. The problem is described in more details here.
The solution is to make sure RegisterMvcIntegratedFilterProvider is called only once in your code for the duration of the complete app domain and since RegisterMvcAttributeFilterProvider is deprecated, prevent having any calls at all to that legacy method. So if you only have one call in there, set a break point on this line, because you might be calling the Initialize() method twice!
The new RegisterMvcIntegratedFilterProvider allows complete integration of MVC attributes in the Simple Injector pipeline which makes sure that the RegisterInitializer method is called on attributes.
Another option though is to enable explicit property injection for attributes, or to fall back on the use of passive attributes as shown here.
But one note on property injection. I noticed you make extensive use of (explicit) property injection, especially for your base classes. From a design perspective however, it's better to remove the base classes all together, because they are a design smell at least, but might become maintenance problems later on. They might violate the Single Responsibility Principle or at least hide that derived types have too many dependencies, which often means too many responsibilities. I create quite big applications myself with MVC and command handlers and query handlers and I am always able to prevent the use of base classes. If a concrete handler needs a dependency, you should simply inject it into the constructor of that type. Prevent hiding that dependency by (ab)using a base type.
There is one important detail that you should be aware about when you use the RegisterMvcIntegratedFilterProvider. MVC caches filter attributes (god knows why) and this means that such attribute is basically becoming a singleton. This implies that every dependency this filter attribute has, becomes a singleton as well. This is of course be big problem if such dependency is not registered as singleton itself; it becomes a captive dependency. Although Simple Injector contains a diagnostic warning to detect these kinds of errors, Simple Injector will be unable to detect this with attributes, because attributes are not registered in the container. Because of this, my advice is to stay away from using property injection in your attributes at all. We are considering to deprecate the RegisterMvcIntegratedFilterProvider method from the MVC integration library.
As per steven It really was calling the container registration twice .
As I got to see tht
I had called SimpleinjectorInitializer.Initialize(); method in global.asax And then the webactivator also calling the same initizer was taking toll on the simpleinjector which caused the initization to fail for a check .
The solution to that is to remove SimpleinjectorInitializer.Initialize(); from the global.asax and let webactivator do its work .

Accessing IAuthSession in non-controller classes in ServiceStack/MVC4

I am new to ServiceStack, so this is probably a noob question:
I am working on an ASP.NET MVC4 application that uses ServiceStack and am trying to figure out how I could get a hold of the current IAuthSession from within a class (either a EF context or a PetaPoco Database) used by my MVC4 controllers derived from ServiceStackController.
The class in question is registered with Funq with the ReuseScope.Request scope (i.e. on the per-HTTP request basis), and ideally I'd like every instance of it to be autowired with the current IAuthSession using either a constructor parameter or a public property.
How do I do that?
UPDATE
After some digging I came up with what I think might work.
In my AppHost.Configure I register a lambda that returns a session from the current request:
container.Register<IAuthSession>(c =>
HttpContext.Current.Request.ToRequest().GetSession());
Also:
container.RegisterAutoWired<EFCatalogDb>();
where EFCatalogDb is my EF context that takes IAuthSession as a constructor argument:
public class EFCatalogDb : DbContext
{
public EFCatalogDb(IAuthSession session) : base()
{ }
// ...etc....
}
Unfortunately I am not at the point in my development when I can test this workaround, so have to ask others if it makes sense at all.
My first suggestion would be to try to keep IAuthSession out of your database classes since that creates a dependency on ServiceStack that seems unnecessary.
That being said, I think you could go the route of registering IAuthSession and having the container automatically inject IAuthSession. A better way might be creating your own 'wrapper class' around IAuthSession and injecting that into your database classes. That would then break the dependency on ServiceStack.
If you have no issue keeping a dependency on ServiceStack another possibility would be using the SessionFeature class and doing something like
var key = SessionFeature.GetSessionKey();
authSession = AppHost.Resolve<ICacheClient>().Get<IAuthSession>(key);

MVC Conditional Dependency Injection

I am trying to figure out the best way to design an MVC4 application with DI via Ninject.
When the user comes to the system, they are presented with a login where they can select one of many databases. Each database is a separate catalog on a database server. What I need to do is inject a repository with the database connection details once the user is logged in. The type of repository does not change, just the connection details.
I have found this post which I could make work, but I am not sure if it is the best approach for my situation. What other options have people used with success?
Problem solved. As I am wishing to pass the connection string in the constructor for my concrete repository I can use the following Ninject WithConstructorArgument:
IBindingWithOrOnSyntax<T> WithConstructorArgument(string name, Func<Ninject.Activation.IContext, object> callback);
With this overload the callback is called every time an object is created. So my code looks like this and the MakeConnectionString method is called every time.
_Kernel = new StandardKernel();
_Kernel.Bind<ISomeItemRepository>().To<FakeSomeItemRepository>()
.WithConstructorArgument("connectionString", (c) =>
{
MakeConnectionString();
});

Resources