Autofac: cannot resolve dependency using factory after ContainerBuilder.Update() -


my problem want use func<> factory resolve dependency. , in if use containerbuilder update() (i need mocking services in integration tests), factories still resolve outdated instances.

i created simple scenario reproduce problem:

class program {     static void main(string[] args)     {         var containerbuilder = new containerbuilder();         containerbuilder.registertype<test>().as<itest>();         containerbuilder.registertype<test1factory>().as<itestfactory>();         containerbuilder.registertype<testconsumer>().asself();         var container = containerbuilder.build();          var tc1 = container.resolve<testconsumer>();          var cbupdater = new containerbuilder();         cbupdater.registertype<test2>().as<itest>();         cbupdater.registertype<test2factory>().as<itestfactory>();         cbupdater.update(container);          var tc2 = container.resolve<testconsumer>();          console.readline();     } }  public interface itest {     int id { get; set; } }  public class test : itest {     public test()     {         id = 1;     }      public int id { get; set; } }  public class test2 : itest {     public test2()     {         id = 2;     }      public int id { get; set; } }  public interface itestfactory {     itest create(); }  public class test1factory : itestfactory {     public itest create()     {         return new test();     } }  public class test2factory : itestfactory {     public itest create()     {         return new test2();     } }  public class testconsumer {     public testconsumer(func<itest> testfactory, itest test, itestfactory customfactory)     {         console.writeline("factory: " + testfactory().id);         console.writeline("direct: " + test.id);         console.writeline("mycustomfactory: " + customfactory.create().id);         console.writeline("*************");         console.writeline();     } } 

the output is:

factory: 1 direct: 1 mycustomfactory: 1


factory: 1 direct: 2 mycustomfactory: 2


notice "factory: 1" in both cases.

am missing or have create cusom factory in scenario?

p.s.

autofac 3.5.2 or 4.0 beta 8-157 .net 4.5.1

that's design unfortunately, reasons, don't know. looking @ autofac code gives better insight on how register items same interface definition, in short, registrations maintained last registration wins (ref). wait...that's not all, weirdly, fun<...>, them in order. can test changing constructor of testconsumer class to:

public testconsumer(func<itest> testfactory, ienumerable<func<itest>> testfactories, ienumerable<itest> tests, itest test, itestfactory customfactory) {     // ... } 

note funcs , itest registration. lucky resolving itest directly resolves test2.

now, having said of above, there way described here. have create container without registration want override, therefore:

/// <summary> /// has not been tested requirements /// </summary> private static icontainer removeoldcomponents(icontainer container) {     var builder = new containerbuilder();     var components = container.componentregistry.registrations                         .where(cr => cr.activator.limittype != typeof(lifetimescope))                         .where(cr => cr.activator.limittype != typeof(func<itest>));     foreach (var c in components)     {         builder.registercomponent(c);     }      foreach (var source in container.componentregistry.sources)     {         builder.registersource(source);     }     return builder.build(); } 

and can change main method following:

static void main(string[] args) {     var containerbuilder = new containerbuilder();     containerbuilder.registertype<test>().as<itest>();     containerbuilder.registertype<test1factory>().as<itestfactory>();     containerbuilder.registertype<testconsumer>().asself();     var container = containerbuilder.build();      var tc1 = container.resolve<testconsumer>();      container = removeoldcomponents(container);      var cbupdater = new containerbuilder();     cbupdater.registertype<test2>().as<itest>();     cbupdater.registertype<test2factory>().as<itestfactory>();     cbupdater.update(container);      var tc2 = container.resolve<testconsumer>();      console.readline(); } 

ps: wouldn't great have method exact opposite of preserveexistingdefaults()


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -