2015-04-29 3 views
0

Если у меня есть следующий модуль:свойства модуля из XML, обеспечивающие значения по умолчанию

class MyModule : Module 
{ 
    public double SomeDouble { get; set; } 
} 

и у меня есть следующий autofac раздел в моем app.config

<autofac> 
    <modules> 
     <module type="MyNamespace.MyModule, MyNamespace"> 
     <properties> 
      <property name="SomeDouble" value="" /> 
     </properties> 
     </module> 
    </modules> 
</autofac> 

При вызове builer.Build()

I получить исключение:

Входная строка не ИНТ правильного формата, значение не является допустимым для двойного

Который имеет смысл.

Что бы я хотел сделать, это предоставить какой-то обработчик для обработки исключения, а не для полного отказа Build() или предоставить значение по умолчанию.

Возможно ли это в пределах autofac на данный момент?

ответ

1

Нет простого способа сделать это. Единственное решение, которое я вижу в том, чтобы обеспечить обычай IConfigurationRegistrar к ConfigurationSettingsReader

var builder = new ContainerBuilder(); 
builder.RegisterModule(new ConfigurationSettingsReader() 
{ 
    ConfigurationRegistrar = new CustomConfigurationRegistrar() 
}); 

builder.Build(); 

The CustomConfigurationRegistrar может наследуется от значения по умолчанию ConfigurationRegistrar. Если вы посмотрите на source code, вы увидите, что RegisterConfiguredModules зарегистрирует весь модуль в цикле foreach, нет способа зарегистрировать один модуль, поэтому вам придется его копировать из базового класса.

Поскольку ошибка исходит из параметра, используемого для ввода свойства, мы можем создать LazyParameter, который обрабатывает ошибку и возвращает значение по умолчанию.

public class CustomConfigurationRegistrar : ConfigurationRegistrar 
{ 
    internal class LazyParameter : Parameter 
    { 
     public LazyParameter(Parameter originalParameter) 
     { 
      this._originalParameter = originalParameter; 
     } 

     private readonly Parameter _originalParameter; 

     public override Boolean CanSupplyValue(ParameterInfo pi, IComponentContext context, out Func<Object> valueProvider) 
     { 
      Boolean canSupplyValue = this._originalParameter.CanSupplyValue(pi, context, out valueProvider); 
      if (canSupplyValue) 
      { 
       Func<Object> originalValueProvider = valueProvider; 
       valueProvider =() => 
       { 
        try 
        { 
         return originalValueProvider(); 
        } 
        catch 
        { 
         Console.WriteLine(pi.Member.Name); 
         // log it and throw or return default value 
         return null; 
        } 
       }; 
      } 
      return canSupplyValue; 
     } 
    } 


    protected override void RegisterConfiguredModules(ContainerBuilder builder, SectionHandler configurationSection) 
    { 
     if (builder == null) 
     { 
      throw new ArgumentNullException("builder"); 
     } 
     if (configurationSection == null) 
     { 
      throw new ArgumentNullException("configurationSection"); 
     } 
     foreach (ModuleElement moduleElement in configurationSection.Modules) 
     { 
      this.RegisterConfiguredModule(builder, configurationSection, moduleElement); 
     } 
    } 

    private void RegisterConfiguredModule(ContainerBuilder builder, SectionHandler configurationSection, ModuleElement moduleElement) 
    { 
     try 
     { 
      var moduleType = this.LoadType(moduleElement.Type, configurationSection.DefaultAssembly); 
      IModule module = null; 

      IEnumerable<Parameter> parameters = moduleElement.Parameters.ToParameters().Select(p => new LazyParameter(p)); 
      IEnumerable<Parameter> properties = moduleElement.Properties.ToParameters().Select(p => new LazyParameter(p)); 

      using (var moduleActivator = new ReflectionActivator(
       moduleType, 
       new DefaultConstructorFinder(), 
       new MostParametersConstructorSelector(), 
       parameters, 
       properties)) 
      { 
       module = (IModule)moduleActivator.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty<Parameter>()); 
      } 
      builder.RegisterModule(module); 
     } 
     catch (Exception) 
     { 
      // log it 
      throw; 
     } 
    } 
} 
+0

Спасибо за это, похоже, это единственный способ на данный момент. Хороший ответ. –

Смежные вопросы