Identity requires me to use this to create a db context:
app.CreatePerOwinContext(EFDbContext.Create);
So I need to get the Microsoft Unity IOC correct.
The issue I was coming across was that I had accidently made 2 database contexts. One for everything else in my application and one for the user stuff. I started writing functions for the user stuff under the wrong context and made it throw errors.
So I decided to use a lifetime manager for my EFDbContext:
// Database context
container.RegisterType<EFDbContext>(new PerThreadLifetimeManager());
// Microsoft identity stuff
container.RegisterType<ApplicationSignInManager>();
container.RegisterType<ApplicationUserManager>();
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(EFDbContext)));
I am wondering if this will cause issues in the future?
Edit:
I found out that the asynchronous stuff in Identity might have been causing an issue with this set up...
I have now used HierarchicalLifetimeManager, it reads like the kind of thing I need... Still unsure if i'm going to come across any issues?
you should be ok - when you do a Resolve or ResolveAll to get the object back from the container and when you are set on using PerThreadLifeTimeManager then Unity will return the same instance for that thread. So unless you are doing multithreaded apps, then you should be fine.
ref: https://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx
I found this article which seemed to do exactly what was needed:
http://www.wiktorzychla.com/2013/03/unity-and-http-per-request-lifetime.html
It has a request lifetime instead of thread or container... I was noticing odd problems when using hierarchical and this second one seems to work a charm!
Related
I'm working on adding push notification into my ASP.NET core 2.0.0 webApp. I want to have a notification service that would have a badgeCount member which I would update when I send out notifications or when I mark something as read.
I wanted to make this a singleton, but it seems like I can't use dependency injection for singletons. I need access to my dbContext and maybe some other Identity /or Entity services later.
Would it make sense for me to make my notifcation service a scopedService instead of a singleton so that I can use DI? Then have a notificationBadge singleton that I would inject into my scopedService so I can maintain it?
I'm doing this so that I don't have to calculate the badge count each time (involves using queries)
EDIT: Actually, after writing this I realized that singletons are probably only instantiated once on server startup and not per user. So my initial approach wouldn't work even if I could use DI. I'd probably have to add a field on my user class that extends the IdentityUser then right? Or is there a way around this so that I don't have to update/save this to any db record?
Understanding DI
So to try and cover your question DI is certainly what you want in terms of most things inside your application and website. It can do singletons, as well as scoped and transcients (new copy every time).
In order to really understand DI and specifically the .Net Core implenentation I actually make use of the DI from .Net Core in a stand-alone .Net Standard open source library so you can see how it is done.
Video explaining the DI and showing me make and use the DI outside of ASP.Net Core scene: https://www.youtube.com/watch?v=PrCoBaQH_aI
Source code: https://github.com/angelsix/dna-framework
This should answer your question regarding how to access the DbContext if you do not understand it already from the video above: https://www.youtube.com/watch?v=JrmtZeJyLgg
Scoped/Transcient vs Singleton
What you have to remember when it comes to whether or not to use a singleton instance is singletons are always in-memory, so you should always consider and try to make things scoped or transcient to save memory, if the creation of that service is not intense or slow. So it is basically a trade off between RAM usage vs speed on some generate grounds.
If you then have specific types of service the decision becomes a different one. For example for DbContext objects you can think of them like a "live, in-memory database query/proxy" and so just like SQL queries you want to create them, execute them and be done with them. That is why they are made scoped, so that when a controller is created (per request) a new DbContext is created, injected, used by an action and then destroyed.
I guess the simple answer is it doesn't usually matter too much and most applications won't have any major concern or issues but you do have to remember singletons stay in-memory for the lifecycle of your application or the app domain if you are in a rare multi-domain setup.
Notification Count
So the main question is really about badges. There are many things involved in this process and setup, and so I will limit my answer to the presumption that you are talking about a client logged into a website and you are providing the website UI, and want to show the badge count for, and that you are not on about for example some Android/iOS app or desktop application.
In terms of generating the badge count it would be a combination of all unread messages or items in your database for the user. I would do this calculation on request from the user visiting a page (So in an Action and returned to the view via Razer or ViewBag for example) that needs that information, or from requesting it via Ajax if you are using a more responsive/Ajax style site.
That again I presume is not an issue and I state it just for completeness and presumptions.
So the issue you are asking about is basically that every time the page changes or the badge count is re-requested you are concerned about the time in getting that information from the database, correct?
Personally I would not bother trying to "cache" this outside of the database, as it is a fast changing thing and you will likely have more hit trying to keep the cache in-sync than just calling the database.
Instead if you are concerned the query will be intensive to work out the badge count, I would instead every time any addition to the database of an unread/new item, or a marking of an item as read is done, you do a "SetUnreadCount" call that calculates and writes that value as a single integer to the database so your call to get the unread count is a Scalar call to the database and SUPER quick.
So I am wrestling with this for quite some time now, but I can't seem to figure it out.
At first I had a datalayer in my solution. This layer is for the communication between the business and the database. It had a generic repository and context objects so it is easy to retrieve and send data from and to the database with EntityFrameWork 6. This all worked very good... but...
Now I notice that in my application (WebAPI 2) I need to change database at runtime. This is really hard to do. It should follow this path:
An external application does a call to my API. In the header of the request is set which database should be used (an Id, or a logic name or whatever, not important now). Before an action is executed some code should read this header-item and set the new connection to the repositories.
This is how I register the repositories for Unity:
container.RegisterType<IContexts.ILanguageCodes<LanguageCode>, Data.LanguageCodes>();
container.RegisterType<IContexts.ISecurityRoles<SecurityRole>, Data.SecurityRoles>();
To show you everything what the implementations of these interfaces are is very much.
To change the connection to an other database I have to change the DBContext, which I know where to find, but the code doesn't. So I started Googling.
Then I found this article: http://rob.conery.io/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/. I read it and all the stuff that is not good is in my project. I was like: Okay, lets start over on the datalayer.
THen I found this article: https://www.danylkoweb.com/Blog/a-better-entity-framework-unit-of-work-pattern-DD. I followed this and came pretty far. But got stuck on the part where the request comes in.
So basicly I am looking for this:
A way to change the connection to an other database at runtime with dependency injection, so I don't have to change the connection everywhere. In the end; the idea of DI is that you don't know where the implementation is, so in this case you don't know where all the connections are.
Does anybody have an example found on the internet I could use to try? Or maybe a good, small example I can focus on?
Long story, I hoped I could make it smaller. I hope someone can help me with this.
Thanks
When I need to support scenarios like this I have one "provisioning" or "configuration" database which holds the connectionstring for each customer/user/whatever. This is separate from the databases which map to the data my application needs.
Whenever the requests comes in you can configure your IOC container with the correct connectionstring, altough I don't know if unity supports this scenario, I know AutoFac / Ninject and most other containers allow changing the container.
I am using a MVC4, C#, Castle Windsor, fluentnhibernate stack for my web application, which generally works very well.
Its only occasionally that I get an error related to nHibernate something along the lines of:
Invalid attempt to call Read when reader is closed.
or
Internal connection fatal error.
This usually rears its ugly head when I do multiple calls, in very close succession.
Currently I am replicating it while doing multiple ajax gets, from JQuery.
What I suspect the problem is, is with my NHibernate session management.
The only thing I can think of is that the calls are someone using the same session, the first one completes and closes it, then the following call is unable to complete.
This shouldn't be possible due to the way my sessions are handled like this:
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(_ => config.BuildSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest());
Should be one session per request right?
How else, or where else can I look for the problem? I am quite stuck.
Of course solved this a few minutes later, but the answer was an eye opener for me.
This answer led me down the right path.
While all of my Repositories, Manager and other layers were installed with the correct lifestyle using Castle Windsor, there was one that wasn't.
I was doing a Repository call from an ActionFilter, all of my action filters are invoked through an ActionInvoker class which was registered incorrectly as Singleton, which resulted in my errors.
container.Register(Component.For<IActionInvoker>()
.ImplementedBy<WindsorActionInvoker>()
.LifeStyle.***Singleton***);
Should of course be
container.Register(Component.For<IActionInvoker>()
.ImplementedBy<WindsorActionInvoker>()
.LifeStyle.Transient);
Just another reminder to pay closer attention to those Lifestyles.
First, some background. We have recently taken on a large MVC3 project. The project was pretty much ready to go live some time ago, then the client decided they wanted to re-theme the whole website and add a load more functionality. They employed us to re-theme the site, finish off the remaining functionality and deploy it.
Generally it is built using a very clear, ordered approach, with one repository for each database table and a clear service layer, however there are some oddities that are making me slightly uncomfortable. The main oddity that keeps on nagging at me is that every single repository and service in the application is completely, 100% static (yes, including methods that write to the db). Of course, this doesn't allow for unit testing, however a greater concern is the potential bottlenecks and threading issues that will cause when the application comes under a heavy load. I am already seeing some unexplained delays in processing requests on the stage server, and that is with a trickle of testing traffic.
The application is so huge that rebuilding it to use IOC/instantiated-per-request repositories is pretty much out of the question.
What can I do to avoid potential threading issues upon deployment? Could i use a connection pool and borrow a db connection each time a write needs to happen?
Thanks in advance :)
Edit - here is some of the code that creates an instance of the entity model. Each static method calls this 'DemoEntities' method to obtain an instance of the entity model, which it then uses to execute the db commands. I can see here that, though the method is static, it is actually checking the HttpRequest for a pre-existing instance and creating one if it doesn't already exist. As such, I think we'll be ok.
public static DemoEntities DemoEntities
{
get
{
if (HttpContext.Current != null && HttpContext.Current.Items["DemoEntities"] == null)
{
HttpContext.Current.Items["DemoEntities"] = new DemoEntities();
}
return HttpContext.Current.Items["DemoEntities"] as DemoEntities;
}
set
{
if (HttpContext.Current != null)
HttpContext.Current.Items["DemoEntities"] = value;
}
}
`
Pat
I assume here that your repository classes only contain static methods, not any static state.
The benefit of stateless static classes is that they can be safely turned into regular classes with default parameterless constructors and no concerns over their life-span. It would then be a simple case to extract an interface for testing purposes.
Whenever you need to talk to a repository, simply instantiate one.
Unless the application is doing something with shared state during repository use, you should not need to be concerned about multi-threaded access. The database itself is responsible for handling many concurrent calls.
Currently all bottlenecks and threading issues are potential, sometimes our educated guesses at what could possibly go wrong are themselves wrong - especially so with multi-threading. The slow down might simply be because the database doesn't have the grunt to cope with too many requests.
On my quest to learn NHibernate I have reached the next hurdle; how should I go about integrating it with StructureMap?
Although code examples are very welcome, I'm more interested in the general procedure.
What I was planning on doing was...
Use Fluent NHibernate to create my class mappings for use in NHibs Configuration
Implement ISession and ISessionFactory
Bootstrap an instance of my ISessionFactory into StructureMap as a singleton
Register ISession with StructureMap, with per-HttpRequest caching
However, don't I need to call various tidy-up methods on my session instance at the end of the HttpRequest (because thats the end of its life)?
If i do the tidy-up in Dispose(), will structuremap take care of this for me?
If not, what am I supposed to do?
Thanks
Andrew
I use StructureMap with fluent-nhibernate (and NH Validator) in 3 of my current projects. 2 of those are ASP MVC apps and the third is a WCF web service.
Your general strategy sounds about right (except you won't be making your own Session or SessionFactory, as was already pointed out in comments). For details, snag my configuration code from here:
http://brendanjerwin.github.com/development/dotnet/2009/03/11/using-nhibernate-validator-with-fluent-nhibernate.html
The post is really about integrating NH Validator and Fluent-NHibernate but you can see exactly how I register the session factory and ISession with StructureMap in the "Bonus" section of the post.
RE: Tidy up: You should try and always work within a transaction and either commit or roll-back the transaction at the end of your unit of work. NH only utilizes SQL Connections when it needs them and will take care of the cleanup of that limited resource for you. Normal garbage collection will take care of your sessions themselves.
The Session Factory is a very expensive object that you will want to only initialize once and keep around for the life of your app.
I've not used structure map but maybee I can still help guide you in the right direction. Fluent nHibernate is awsome good choice over the hbm files.
As for the http request, you do not need to ensure that you close the session when the http request ends. If you don't you'll end up leaking nHibernate session. I'm not sure if structure map will handle this for you, what I've done is I have an http module which closes the session.
One thing to note though that bite me, is that you will make to sure you wrap all your data access in a transaction and ensure nHibernate actually commits its changes. If you do this as part of your session close, you could miss the chance to handle errors. I'm curious to hear what you ended up having to do to get this workign.