c# - Autofac Dependency resolution in constructor vs resolution in the method of usage -


before begin question, here background of application:

  • application: web application using asp.net mvc , c#
  • orm: entity framework
  • dependency injection container: autofac

consider have class serves lookup class database tables. database contains 350 tables. following simplified example shows structure in application.

(if think you've got scenario, can directly jump question @ bottom.)

here lookup class

public class lookup {     private readonly irepository<table001> _table001repository;     // repositories table002 table349     private readonly irepository<table350> _table350repository;      public lookup(         irepository<table001> table001repository,         // parameters table002repository table349repository         irepository<table350> table350repository)     {         _table001repository = table001repository;         // assignments table002repository table349repository         _table350repository = table350repository;     }      public table001 gettable001(/* fields looking table001 */)     {         // lookup logic using repository table001, namely _table001repository     }      // other lookup methods table002 table349      public table350 gettable350(/* fields looking table350 */)     {         // lookup logic using repository table350, namely _table350repository     } } 

now, example class uses lookup class:

public class myclass {     private readonly ilookup _lookup;      public myclass(ilookup lookup)     {         _lookup = lookup;     }      public method()     {         table001 table001 = _lookup.gettable001(/* fields */);         table002 table002 = _lookup.gettable002(/* fields */);         table003 table003 = _lookup.gettable003(/* fields */);         ...     } } 

registrations autofac done way:

// lookup class registration builder.registertype<lookup>().as<ilookup>().instanceperlifetimescope();  // generic registration repositories builder.registergeneric(typeof(repository<>)).as(typeof(irepository<>)).instanceperlifetimescope(); 

question:

as can see, class makes use of lookup class using 3 methods 350 lookup methods. while instantiating lookup class in myclass (the _lookup field), 350 repositories resolved too, instantiating 350 repositories. concern regarding performance/efficiency. of following 2 options better performance wise, , why?

  1. resolving dependencies being done now, using auto-injection in constructor.
  2. resolving repository in method uses repository instead of auto-injection in constructor. example gettable001() become (the field _table001repository removed lookup class, parameter table001repository in constructor):

    public table001 gettable001(/* fields looking table001 */) {     irepository<table001> table001repository = container.resolve<irepository<table001>>();     // lookup logic } 

in option 1, 350 repositories instantiated while resolving _lookup, though, example, class myclass uses 3 lookup methods. second approach better first? or, first option better second performance-wise? also, scope of resolution (instanceperlifetimescope, instanceperdependency, etc.) make difference?

thanks.


ps: please comment if think question should better posted in softwareengineering. reason of asking here broad audience has.

there few different things consider here:

first, else using ilookup instance? if so, have instance of 350 repositories created, doesn't matter in respect.

second, non constructor resolution of injected members (e.g. using servicelocator) considered anti-pattern (http://blog.ploeh.dk/2010/02/03/servicelocatorisananti-pattern/). thus, try avoid if possible. biggest reason why (as outlined in article) hides class dependencies consumers.

third, there reason cannot create new service consists of necessary repository dependency? if can create imyclasslookup service implements ilookup interface has necessary repositories need, that's easiest , cleanest way go. register new service , use in constructor:

new interface

public interface imyclasslookup : ilookup { } 

new class

public class myclasslookup : imyclasslookup {     private readonly iwhateverrepository _whateverrepository;      public myclasslookup(iwhateverrepository whateverrepository)     {         _whateverrepository = whateverrepository;     }      // imyclasslookup implementations here use _whateverrepository } 

dependency registration

builder.registertype<myclasslookup>().as<imyclasslookup>().instanceperlifetimescope(); 

your class

public class myclass {     private readonly imyclasslookup _myclasslookup;      public myclass(imyclasslookup myclasslookup)     {         _myclasslookup = myclasslookup;     }      public method()     {         table001 table001 = _myclasslookup.gettable001(/* fields */);         table002 table002 = _myclasslookup.gettable002(/* fields */);         table003 table003 = _myclasslookup.gettable003(/* fields */);         ...     } } 

Comments