Monday, April 6, 2020

How to I fill in the ConfigurationModule for namespace Autofac.Extras.Configuration in .NET Core?

Following up on this, how do we port this?

namespace Autofac.Extras.Configuration
{
   public sealed class ConfigurationModule : Module
   {
      protected override void Load(ContainerBuilder builder);
   }
}

 
 

We could have something like so but it is a guess in the dark honestly.

using Autofac;
namespace Anything.You.Like.Here
{
   public sealed class ConfigurationModule : Module
   {
      protected override void Load(ContainerBuilder builder) { }
   }
}

 
 

Addendum 4/7/2020: After some thought and some use of dotPeek, I think we should instead have:

using Autofac.Core;
namespace Autofac.Extras.Configuration
{
   public sealed class ConfigurationModule : Module
   {
      protected void Load(ContainerBuilder builder)
      {
         RegistrationExtensions.RegisterInstance(builder, (IRegistrationSource)new
               ConfigurationRegistrationSource());
      }
   }
}

 
 

That part is pretty easy, but it opens the door to...

using Autofac.Builder;
using Autofac.Core;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using ConfigurationSection = System.Configuration.ConfigurationSection;
namespace Autofac.Extras.Configuration
{
   internal class ConfigurationRegistrationSource : IRegistrationSource
   {
      public bool IsAdapterForIndividualComponents
      {
         get
         {
            return false;
         }
      }
      
      public IEnumerable<IComponentRegistration> RegistrationsFor(Service service,
            Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
      {
         if (!(service is IServiceWithType iserviceWithType)) return
               Enumerable.Empty<IComponentRegistration>();
         Type type = (Type)iserviceWithType.ServiceType;
         if (!typeof(ConfigurationSection).IsAssignableFrom(type) &&
               !typeof(ConfigurationSectionGroup).IsAssignableFrom(type)) return
               Enumerable.Empty<IComponentRegistration>();
         KeyedService keyedService = service as KeyedService;
         string name = keyedService == null ? (string)null :
               Convert.ToString(keyedService.ServiceKey,
               (IFormatProvider)CultureInfo.InvariantCulture);
         if (string.IsNullOrEmpty(name)) return
               Enumerable.Empty<IComponentRegistration>();
         IList<string> stack = ConfigurationRegistrationSource.RecurseSectionNames(type,
               name);
         IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrationStyle>
               iregistrationBuilder1 = RegistrationBuilder.ForDelegate((Type)type,
               (Func<IComponentContext, IEnumerable<Parameter>, object>)((c, p) =>
               ConfigurationRegistrationSource.SectionResolver(type, stack)));
         IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrationStyle>
               iregistrationBuilder2;
         if (name != null)
            iregistrationBuilder2 = iregistrationBuilder1.Named(name, (Type)type);
         else
            iregistrationBuilder2 = iregistrationBuilder1.As((Type[])new Type[1] { type });
         return (IEnumerable<IComponentRegistration>)new IComponentRegistration[1] {
               RegistrationBuilder.CreateRegistration<object, SimpleActivatorData,
               SingleRegistrationStyle>(iregistrationBuilder2) };
      }
      
      private static object SectionResolver(Type type, IList<string> stack)
      {
         IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json",
               optional: true, reloadOnChange: true).Build();
         return (object) config.GetSection(type.ToString());
      }
      
      private static IList<string> RecurseSectionNames(Type type, string name)
      {
         DefaultSectionGroupAttribute customAttribute =
               type.GetCustomAttribute<DefaultSectionGroupAttribute>(false);
         IList<string> stringList = customAttribute == null ? (IList<string>)new List<string>() :
               ConfigurationRegistrationSource.RecurseSectionNames(customAttribute
               .ParentType, customAttribute.ParentName);
         stringList.Add(name ?? ConfigurationRegistrationSource.GetDefaultName(type));
         return stringList;
      }
      
      private static string GetDefaultName(Type type)
      {
         DefaultNameAttribute customAttribute =
               type.GetCustomAttribute<DefaultNameAttribute>(false);
         if (customAttribute == null) throw new
               DependencyResolutionException("ConfigurationSection type " + (object)type +
               " does not have Default Name Attribute");
         return customAttribute.Name;
      }
   }
}

No comments:

Post a Comment