asp.net mvc - Autofac (+MVC + EF + SignalR + Hangfire) lifetime scopes -


i have asp.net mvc project uses entity framwork, signalr , hangfire jobs.

my main (root) container defined way:

builder.registertype<dbcontext>().instanceperlifetimescope(); // ef db context builder.registertype<chatservice>().as<ichatservice>().singleinstance(); // classic "service", has dependency on dbcontext builder.registertype<chathub>().externallyowned(); // signalr hub builder.registertype<updatestatusesjob>().instanceperdependency(); // hangfire job builder.registertype<homecontroller>().instanceperrequest(); // asp.net mvc controller icontainer container = builder.build(); 

for mvc i'm using autofac.mvc5 nuget package. dependency resolver:

dependencyresolver.setresolver(new autofacdependencyresolver(container)); 

for signalr i'm using autofac.signalr nuget package. dependency resolver:

globalhost.dependencyresolver = new autofac.integration.signalr.autofacdependencyresolver(container); 

my signalr hub instantiated way (http://autofac.readthedocs.org/en/latest/integration/signalr.html#managing-dependency-lifetimes):

private ilifetimescope _hubscope; protected ichatservice chatservice; public chathub(ilifetimescope scope) {   _hubscope = scope.beginlifetimescope(); // scope    chatservice = _hubscope.resolve<ichatservice>(); // service used in hub methods } protected override void dispose(bool disposing) {   // dipose hub lifetime scope when hub disposed.   if (disposing && _hubscope != null)   {     _hubscope.dispose();   }   base.dispose(disposing); } 

for hangfire i'm using hangfire.autofac package:

config.useactivator(new autofacjobactivator(container)); 

jobs instantiated way:

private readonly ilifetimescope _jobscope; protected ichatservice chatservice; protected basejob(ilifetimescope scope) {     _jobscope = scope.beginlifetimescope();     chatservice = _jobscope.resolve<ichatservice>(); } public void dispose() {     _jobscope.dispose(); } 

question/problem: same instance of dbcontext in hubs , jobs. want hub instances same chatservice, dbcontext (which dependency of chatservice) new instance. hangfire jobs should act same.

can done, or missing something?

update 1:

after thinking (and sleeping over) think have 2 choices. still want to keep "session per request" ("session per hub", "session per job").

option 1:

change services have instanceperlifetimescope. instantiation of services not expensive. services maintains kind of state create "storage" (class) singleinstance , not have dependency on session (dbcontext). think work hubs , jobs also.

option 2:

create kind of factory suggested @ric .net. this:

public class dbfactory: idbfactory {     public mydbcontext getdb()     {         if (httpcontext.current != null)         {             var db = httpcontext.current.items["db"] mydbcontext;             if (db == null)             {                 db = new mydbcontext();                 httpcontext.current.items["db"] = db;             }             return db;         }          // jobs , hubs?         return new mydbcontext();     } }      protected void application_endrequest(object sender, eventargs e)     {         var db = httpcontext.current.items["db"] mydbcontext;         if (db != null)         {             db.dispose();         }     } 

i think work mvc, don't know hot working hubs (every hub call new instance of hub) , jobs (every run of job new instance of job class).

i leaning towards option 1. think?

many thanks!

i'm unexperienced autofac. got attention was:

i want hub instances same chatservice, dbcontext (which dependency of chatservice) new instance.

what you're saying here is:

"my car in maintenance same car company have dependency on garage, everytime bring car want garage new one".

when inject (completely build instance, including dependencies of) chatservice in other component, of course other dependencies has build also, whether have other kind of lifestyle or not. when object shorter lifetime object injected in created, you've created called 'captive dependency'

the way new 'instance' of dbcontext in chatservice not inject dbcontext injecting dbcontextfactory creates dbcontext whenever use it.

an implementation like:

public class dbcontextfactory {     public dbcontext create()     {          return new dbcontext();     } }  //usage: public class chatservice {      private readonly dbcontextfactory dbcontextfactory;       public chatservice(dbcontextfactory dbcontextfactory)      {          this.dbcontextfactory = dbcontextfactory;      }      public void somemethodinchatservice()     {          using (var db = this.dbcontextfactory.create())          {              //do dbcontext              }      } } 

the dbcontextfactory registered in autofac using singleton lifestyle.

this maybe not aim for. because in case every time use dbcontext new one. on other hand, new dbcontext safest way approach this, can read here.

this great answer worth reading more 1 reason because has explanation of how use command / handler pattern should suitable situation.

this make chatservice unknowing of dbcontext improves 'solid' design of application , creates possibilty test chatservice practically undoable when injecting dbcontext or dbcontextfactory directly.


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

python - NameError: name 'subprocess' is not defined -