How to get Simple injector to auto resolve interface when it only has one concrete?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







3















Currently i have a webapi controller with the constructor like this:



readonly IQueryFactory queryFactory;
readonly ICommandFactory commandFactory;

public UserBenefitsController(
IQueryFactory queryFactory,
ICommandFactory commandFactory)
{
this.queryFactory = queryFactory;
this.commandFactory = commandFactory;
}


I am using simple injector to register both of these types.



container.RegisterWebApiRequest<IQueryFactory, QueryFactory>();
container.RegisterWebApiRequest<ICommandFactory, CommandFactory>();


But i am finding that as i continue to develop my app that I am continuing to have a lot of ISomeInterface resolving to ISomeConcrete with 1:1 ratio.



Is it possible to tell simple injector to look for at an interface and automatically resolve it when there is only 1 concrete for it within the WebApiRequest scope?










share|improve this question































    3















    Currently i have a webapi controller with the constructor like this:



    readonly IQueryFactory queryFactory;
    readonly ICommandFactory commandFactory;

    public UserBenefitsController(
    IQueryFactory queryFactory,
    ICommandFactory commandFactory)
    {
    this.queryFactory = queryFactory;
    this.commandFactory = commandFactory;
    }


    I am using simple injector to register both of these types.



    container.RegisterWebApiRequest<IQueryFactory, QueryFactory>();
    container.RegisterWebApiRequest<ICommandFactory, CommandFactory>();


    But i am finding that as i continue to develop my app that I am continuing to have a lot of ISomeInterface resolving to ISomeConcrete with 1:1 ratio.



    Is it possible to tell simple injector to look for at an interface and automatically resolve it when there is only 1 concrete for it within the WebApiRequest scope?










    share|improve this question



























      3












      3








      3








      Currently i have a webapi controller with the constructor like this:



      readonly IQueryFactory queryFactory;
      readonly ICommandFactory commandFactory;

      public UserBenefitsController(
      IQueryFactory queryFactory,
      ICommandFactory commandFactory)
      {
      this.queryFactory = queryFactory;
      this.commandFactory = commandFactory;
      }


      I am using simple injector to register both of these types.



      container.RegisterWebApiRequest<IQueryFactory, QueryFactory>();
      container.RegisterWebApiRequest<ICommandFactory, CommandFactory>();


      But i am finding that as i continue to develop my app that I am continuing to have a lot of ISomeInterface resolving to ISomeConcrete with 1:1 ratio.



      Is it possible to tell simple injector to look for at an interface and automatically resolve it when there is only 1 concrete for it within the WebApiRequest scope?










      share|improve this question
















      Currently i have a webapi controller with the constructor like this:



      readonly IQueryFactory queryFactory;
      readonly ICommandFactory commandFactory;

      public UserBenefitsController(
      IQueryFactory queryFactory,
      ICommandFactory commandFactory)
      {
      this.queryFactory = queryFactory;
      this.commandFactory = commandFactory;
      }


      I am using simple injector to register both of these types.



      container.RegisterWebApiRequest<IQueryFactory, QueryFactory>();
      container.RegisterWebApiRequest<ICommandFactory, CommandFactory>();


      But i am finding that as i continue to develop my app that I am continuing to have a lot of ISomeInterface resolving to ISomeConcrete with 1:1 ratio.



      Is it possible to tell simple injector to look for at an interface and automatically resolve it when there is only 1 concrete for it within the WebApiRequest scope?







      c# asp.net-web-api simple-injector






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '14 at 18:56









      qujck

      12k42964




      12k42964










      asked Nov 14 '14 at 16:17









      4imble4imble

      8,1071355109




      8,1071355109
























          2 Answers
          2






          active

          oldest

          votes


















          6














          You can use batch / automatic registration to resolve to concrete instances.
          The Simple Injector documentation explains it here



          For instance:



          ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();

          var assembly = typeof(YourRepository).Assembly;

          var registrations =
          from type in assembly.GetExportedTypes()
          where type.Namespace == "Acme.YourRepositories"
          where type.GetInterfaces().Any()
          select new
          {
          Service = type.GetInterfaces().Single(),
          Implementation = type
          };

          foreach (var reg in registrations)
          container.Register(reg.Service, reg.Implementation, scopedLifestyle);





          share|improve this answer


























          • I get an "Sequence contains more than one element" exception when I do this in the section.

            – pmbanugo
            Apr 28 '16 at 13:42











          • I've used the second answer to this question to resolve my problem. Thanks

            – pmbanugo
            Apr 28 '16 at 13:57



















          5














          Besides the correct (and probably preferable) answer of Mr Bacardi, you can also achieve this using unregistered type resolution, using the following extension method:



          public static void AutoMap(this Container container, params Assembly assemblies) {
          container.ResolveUnregisteredType += (s, e) => {
          if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
          Type concreteTypes = (
          from assembly in assemblies
          from type in assembly.GetTypes()
          where !type.IsAbstract && !type.IsGenericType
          where e.UnregisteredServiceType.IsAssignableFrom(type)
          select type)
          .ToArray();

          if (concreteTypes.Length == 1) {
          e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
          container));
          }
          }
          };
          }


          You can use this extension method as follows:



          container.AutoMap(Assembly.GetExecutingAssembly());


          It is important that you apply a strict set of assemblies to this method, containing only the production assemblies. When you apply all AppDomain assemblies, you'll find that it is likely to fail in your integration or unit test suite, since you will likely have fake implementations of those interfaces in those assemblies.



          My preference though is to do as much explicit up front registration as possible, which is the solution that Mr Bacardi describes. The method described here uses a 'just in time' approach, where it starts to look for an implementation on the first resolve. If you call container.Verify() however, you will be safe in most cases, although it is possible that a call to Verify() succeeds, while resolving object graphs fails as runtime, because Verify() will only verify objects that are known to the configuration. So you will have to make sure that your unregistered interfaces are directly or indirectly referenced by something that actually is registered. Since it is easy to overlook such thing, I prefer Mr Barardi's approach.



          But I must admit that in the applications I work on (which are usually quite big), we have just a few of those 'one-to-one' implementations. Most implementations in the system implement a generic interface (such as this and this) and there's hardly ever a reason for me to do batch registration on those non-generic interfaces. Simple Injector on the other hand has great support for batch registering generic interfaces using the Register methods.






          share|improve this answer


























          • Excellent information, many thanks for taking the time to give an alternative.

            – 4imble
            Nov 17 '14 at 8:59












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26934325%2fhow-to-get-simple-injector-to-auto-resolve-interface-when-it-only-has-one-concre%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          6














          You can use batch / automatic registration to resolve to concrete instances.
          The Simple Injector documentation explains it here



          For instance:



          ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();

          var assembly = typeof(YourRepository).Assembly;

          var registrations =
          from type in assembly.GetExportedTypes()
          where type.Namespace == "Acme.YourRepositories"
          where type.GetInterfaces().Any()
          select new
          {
          Service = type.GetInterfaces().Single(),
          Implementation = type
          };

          foreach (var reg in registrations)
          container.Register(reg.Service, reg.Implementation, scopedLifestyle);





          share|improve this answer


























          • I get an "Sequence contains more than one element" exception when I do this in the section.

            – pmbanugo
            Apr 28 '16 at 13:42











          • I've used the second answer to this question to resolve my problem. Thanks

            – pmbanugo
            Apr 28 '16 at 13:57
















          6














          You can use batch / automatic registration to resolve to concrete instances.
          The Simple Injector documentation explains it here



          For instance:



          ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();

          var assembly = typeof(YourRepository).Assembly;

          var registrations =
          from type in assembly.GetExportedTypes()
          where type.Namespace == "Acme.YourRepositories"
          where type.GetInterfaces().Any()
          select new
          {
          Service = type.GetInterfaces().Single(),
          Implementation = type
          };

          foreach (var reg in registrations)
          container.Register(reg.Service, reg.Implementation, scopedLifestyle);





          share|improve this answer


























          • I get an "Sequence contains more than one element" exception when I do this in the section.

            – pmbanugo
            Apr 28 '16 at 13:42











          • I've used the second answer to this question to resolve my problem. Thanks

            – pmbanugo
            Apr 28 '16 at 13:57














          6












          6








          6







          You can use batch / automatic registration to resolve to concrete instances.
          The Simple Injector documentation explains it here



          For instance:



          ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();

          var assembly = typeof(YourRepository).Assembly;

          var registrations =
          from type in assembly.GetExportedTypes()
          where type.Namespace == "Acme.YourRepositories"
          where type.GetInterfaces().Any()
          select new
          {
          Service = type.GetInterfaces().Single(),
          Implementation = type
          };

          foreach (var reg in registrations)
          container.Register(reg.Service, reg.Implementation, scopedLifestyle);





          share|improve this answer















          You can use batch / automatic registration to resolve to concrete instances.
          The Simple Injector documentation explains it here



          For instance:



          ScopedLifestyle scopedLifestyle = new WebApiRequestLifestyle();

          var assembly = typeof(YourRepository).Assembly;

          var registrations =
          from type in assembly.GetExportedTypes()
          where type.Namespace == "Acme.YourRepositories"
          where type.GetInterfaces().Any()
          select new
          {
          Service = type.GetInterfaces().Single(),
          Implementation = type
          };

          foreach (var reg in registrations)
          container.Register(reg.Service, reg.Implementation, scopedLifestyle);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 16 '14 at 12:20









          Steven

          129k17224342




          129k17224342










          answered Nov 14 '14 at 16:59









          Mr BacardiMr Bacardi

          761




          761













          • I get an "Sequence contains more than one element" exception when I do this in the section.

            – pmbanugo
            Apr 28 '16 at 13:42











          • I've used the second answer to this question to resolve my problem. Thanks

            – pmbanugo
            Apr 28 '16 at 13:57



















          • I get an "Sequence contains more than one element" exception when I do this in the section.

            – pmbanugo
            Apr 28 '16 at 13:42











          • I've used the second answer to this question to resolve my problem. Thanks

            – pmbanugo
            Apr 28 '16 at 13:57

















          I get an "Sequence contains more than one element" exception when I do this in the section.

          – pmbanugo
          Apr 28 '16 at 13:42





          I get an "Sequence contains more than one element" exception when I do this in the section.

          – pmbanugo
          Apr 28 '16 at 13:42













          I've used the second answer to this question to resolve my problem. Thanks

          – pmbanugo
          Apr 28 '16 at 13:57





          I've used the second answer to this question to resolve my problem. Thanks

          – pmbanugo
          Apr 28 '16 at 13:57













          5














          Besides the correct (and probably preferable) answer of Mr Bacardi, you can also achieve this using unregistered type resolution, using the following extension method:



          public static void AutoMap(this Container container, params Assembly assemblies) {
          container.ResolveUnregisteredType += (s, e) => {
          if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
          Type concreteTypes = (
          from assembly in assemblies
          from type in assembly.GetTypes()
          where !type.IsAbstract && !type.IsGenericType
          where e.UnregisteredServiceType.IsAssignableFrom(type)
          select type)
          .ToArray();

          if (concreteTypes.Length == 1) {
          e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
          container));
          }
          }
          };
          }


          You can use this extension method as follows:



          container.AutoMap(Assembly.GetExecutingAssembly());


          It is important that you apply a strict set of assemblies to this method, containing only the production assemblies. When you apply all AppDomain assemblies, you'll find that it is likely to fail in your integration or unit test suite, since you will likely have fake implementations of those interfaces in those assemblies.



          My preference though is to do as much explicit up front registration as possible, which is the solution that Mr Bacardi describes. The method described here uses a 'just in time' approach, where it starts to look for an implementation on the first resolve. If you call container.Verify() however, you will be safe in most cases, although it is possible that a call to Verify() succeeds, while resolving object graphs fails as runtime, because Verify() will only verify objects that are known to the configuration. So you will have to make sure that your unregistered interfaces are directly or indirectly referenced by something that actually is registered. Since it is easy to overlook such thing, I prefer Mr Barardi's approach.



          But I must admit that in the applications I work on (which are usually quite big), we have just a few of those 'one-to-one' implementations. Most implementations in the system implement a generic interface (such as this and this) and there's hardly ever a reason for me to do batch registration on those non-generic interfaces. Simple Injector on the other hand has great support for batch registering generic interfaces using the Register methods.






          share|improve this answer


























          • Excellent information, many thanks for taking the time to give an alternative.

            – 4imble
            Nov 17 '14 at 8:59
















          5














          Besides the correct (and probably preferable) answer of Mr Bacardi, you can also achieve this using unregistered type resolution, using the following extension method:



          public static void AutoMap(this Container container, params Assembly assemblies) {
          container.ResolveUnregisteredType += (s, e) => {
          if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
          Type concreteTypes = (
          from assembly in assemblies
          from type in assembly.GetTypes()
          where !type.IsAbstract && !type.IsGenericType
          where e.UnregisteredServiceType.IsAssignableFrom(type)
          select type)
          .ToArray();

          if (concreteTypes.Length == 1) {
          e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
          container));
          }
          }
          };
          }


          You can use this extension method as follows:



          container.AutoMap(Assembly.GetExecutingAssembly());


          It is important that you apply a strict set of assemblies to this method, containing only the production assemblies. When you apply all AppDomain assemblies, you'll find that it is likely to fail in your integration or unit test suite, since you will likely have fake implementations of those interfaces in those assemblies.



          My preference though is to do as much explicit up front registration as possible, which is the solution that Mr Bacardi describes. The method described here uses a 'just in time' approach, where it starts to look for an implementation on the first resolve. If you call container.Verify() however, you will be safe in most cases, although it is possible that a call to Verify() succeeds, while resolving object graphs fails as runtime, because Verify() will only verify objects that are known to the configuration. So you will have to make sure that your unregistered interfaces are directly or indirectly referenced by something that actually is registered. Since it is easy to overlook such thing, I prefer Mr Barardi's approach.



          But I must admit that in the applications I work on (which are usually quite big), we have just a few of those 'one-to-one' implementations. Most implementations in the system implement a generic interface (such as this and this) and there's hardly ever a reason for me to do batch registration on those non-generic interfaces. Simple Injector on the other hand has great support for batch registering generic interfaces using the Register methods.






          share|improve this answer


























          • Excellent information, many thanks for taking the time to give an alternative.

            – 4imble
            Nov 17 '14 at 8:59














          5












          5








          5







          Besides the correct (and probably preferable) answer of Mr Bacardi, you can also achieve this using unregistered type resolution, using the following extension method:



          public static void AutoMap(this Container container, params Assembly assemblies) {
          container.ResolveUnregisteredType += (s, e) => {
          if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
          Type concreteTypes = (
          from assembly in assemblies
          from type in assembly.GetTypes()
          where !type.IsAbstract && !type.IsGenericType
          where e.UnregisteredServiceType.IsAssignableFrom(type)
          select type)
          .ToArray();

          if (concreteTypes.Length == 1) {
          e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
          container));
          }
          }
          };
          }


          You can use this extension method as follows:



          container.AutoMap(Assembly.GetExecutingAssembly());


          It is important that you apply a strict set of assemblies to this method, containing only the production assemblies. When you apply all AppDomain assemblies, you'll find that it is likely to fail in your integration or unit test suite, since you will likely have fake implementations of those interfaces in those assemblies.



          My preference though is to do as much explicit up front registration as possible, which is the solution that Mr Bacardi describes. The method described here uses a 'just in time' approach, where it starts to look for an implementation on the first resolve. If you call container.Verify() however, you will be safe in most cases, although it is possible that a call to Verify() succeeds, while resolving object graphs fails as runtime, because Verify() will only verify objects that are known to the configuration. So you will have to make sure that your unregistered interfaces are directly or indirectly referenced by something that actually is registered. Since it is easy to overlook such thing, I prefer Mr Barardi's approach.



          But I must admit that in the applications I work on (which are usually quite big), we have just a few of those 'one-to-one' implementations. Most implementations in the system implement a generic interface (such as this and this) and there's hardly ever a reason for me to do batch registration on those non-generic interfaces. Simple Injector on the other hand has great support for batch registering generic interfaces using the Register methods.






          share|improve this answer















          Besides the correct (and probably preferable) answer of Mr Bacardi, you can also achieve this using unregistered type resolution, using the following extension method:



          public static void AutoMap(this Container container, params Assembly assemblies) {
          container.ResolveUnregisteredType += (s, e) => {
          if (e.UnregisteredServiceType.IsInterface && !e.Handled) {
          Type concreteTypes = (
          from assembly in assemblies
          from type in assembly.GetTypes()
          where !type.IsAbstract && !type.IsGenericType
          where e.UnregisteredServiceType.IsAssignableFrom(type)
          select type)
          .ToArray();

          if (concreteTypes.Length == 1) {
          e.Register(Lifestyle.Transient.CreateRegistration(concreteTypes[0],
          container));
          }
          }
          };
          }


          You can use this extension method as follows:



          container.AutoMap(Assembly.GetExecutingAssembly());


          It is important that you apply a strict set of assemblies to this method, containing only the production assemblies. When you apply all AppDomain assemblies, you'll find that it is likely to fail in your integration or unit test suite, since you will likely have fake implementations of those interfaces in those assemblies.



          My preference though is to do as much explicit up front registration as possible, which is the solution that Mr Bacardi describes. The method described here uses a 'just in time' approach, where it starts to look for an implementation on the first resolve. If you call container.Verify() however, you will be safe in most cases, although it is possible that a call to Verify() succeeds, while resolving object graphs fails as runtime, because Verify() will only verify objects that are known to the configuration. So you will have to make sure that your unregistered interfaces are directly or indirectly referenced by something that actually is registered. Since it is easy to overlook such thing, I prefer Mr Barardi's approach.



          But I must admit that in the applications I work on (which are usually quite big), we have just a few of those 'one-to-one' implementations. Most implementations in the system implement a generic interface (such as this and this) and there's hardly ever a reason for me to do batch registration on those non-generic interfaces. Simple Injector on the other hand has great support for batch registering generic interfaces using the Register methods.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 16 '18 at 15:46

























          answered Nov 14 '14 at 20:27









          StevenSteven

          129k17224342




          129k17224342













          • Excellent information, many thanks for taking the time to give an alternative.

            – 4imble
            Nov 17 '14 at 8:59



















          • Excellent information, many thanks for taking the time to give an alternative.

            – 4imble
            Nov 17 '14 at 8:59

















          Excellent information, many thanks for taking the time to give an alternative.

          – 4imble
          Nov 17 '14 at 8:59





          Excellent information, many thanks for taking the time to give an alternative.

          – 4imble
          Nov 17 '14 at 8:59


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26934325%2fhow-to-get-simple-injector-to-auto-resolve-interface-when-it-only-has-one-concre%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Bressuire

          Vorschmack

          Quarantine