Castle Windsor: как указать значение времени выполнения в качестве параметра (например, значение, возвращаемое при статическом вызове функции) - PullRequest
2 голосов
/ 19 декабря 2008

Я хочу выполнить этот CODE эквивалент в файле конфигурации Castle XML.

// Foo (имя строки)

IFoo f = new Foo (StaticBarClass.Name);




XML

Теперь что касается XML, я знаю все (например, бла), за исключением содержимого в части параметров.

Как будет выглядеть часть параметра?

<component id="blah"
           service="blah"
           type="blah">
  <parameters>
    <name>StaticBarClas.Name_THAT_I_NEED_HELP_WITH</name>
  </parameters>

Ответы [ 2 ]

1 голос
/ 21 декабря 2008

Один из подходов, который вы могли бы использовать, - это заменить инспектор параметров конфигурации своим собственным вариантом, который может вводить некоторое дополнительное поведение - вот быстрый прототип:

public class ExtendedConfigurationParametersInspector : IContributeComponentModelConstruction
{
  #region IContributeComponentModelConstruction Members

  public virtual void ProcessModel(IKernel kernel, ComponentModel model)
  {
    if (model.Configuration == null) return;

    IConfiguration parameters = model.Configuration.Children["parameters"];

    if (parameters == null) return;

    foreach (IConfiguration parameter in parameters.Children)
    {
      String name = parameter.Name;
      String value = parameter.Value;

      if (value == null && parameter.Children.Count != 0)
      {
        IConfiguration parameterValue = parameter.Children[0];
        model.Parameters.Add(name, parameterValue);
      }
      else
      {
        if (parameter.Attributes["type"] == "static")
        {
          int lastIndex = parameter.Value.LastIndexOf(".");
          string typeName = parameter.Value.Substring(0, lastIndex);
          string field = parameter.Value.Substring(lastIndex + 1);
          Type ownerType = Type.GetType(typeName);
          FieldInfo valueField = ownerType.GetField(field);
          value = (string) valueField.GetValue(null);
        }

        model.Parameters.Add(name, value);
      }
    }

    foreach (ParameterModel parameter in model.Parameters)
    {
      if (parameter.Value == null || !ReferenceExpressionUtil.IsReference(parameter.Value))
      {
        continue;
      }

      String newKey = ReferenceExpressionUtil.ExtractComponentKey(parameter.Value);

      model.Dependencies.Add(new DependencyModel(DependencyType.ServiceOverride, newKey, null, false));
    }
  }

  #endregion
}

public class ExtendedComponentBuilder : DefaultComponentModelBuilder
{
  public ExtendedComponentBuilder(IKernel kernel) : base(kernel)
  {
  }

  protected override void InitializeContributors()
  {
    AddContributor(new GenericInspector());
    AddContributor(new ConfigurationModelInspector());
    AddContributor(new ExtendedConfigurationParametersInspector());
    AddContributor(new LifestyleModelInspector());
    AddContributor(new ConstructorDependenciesModelInspector());
    AddContributor(new PropertiesDependenciesModelInspector());
    AddContributor(new LifecycleModelInspector());
    AddContributor(new InterceptorInspector());
    AddContributor(new ComponentActivatorInspector());
    AddContributor(new ComponentProxyInspector());
  }
}

public class ExtendedWindsorContainer : WindsorContainer
{
  public ExtendedWindsorContainer(IConfigurationInterpreter interpreter)
    : base(CreateKernel(), new Castle.Windsor.Installer.DefaultComponentInstaller())
  {
    if (interpreter == null) throw new ArgumentNullException("interpreter");

    interpreter.ProcessResource(interpreter.Source, Kernel.ConfigurationStore);

    RunInstaller();
  }

  private static IKernel CreateKernel()
  {
    DefaultKernel kernel = new DefaultKernel();
    kernel.ComponentModelBuilder = new ExtendedComponentBuilder(kernel);
    return kernel;
  }
}

Затем вы можете подключить свойства в вашем контейнере следующим образом: указание типа «статический» для параметра приведет к замене значения на статическое поле, на которое ссылается значение параметров.

<castle>
  <components>
    <component id="test"
           type="SomeNamespace.TestComponent,Example">
      <parameters>
        <value type="static">SomeNamespace.SomeClass.TheStaticFieldValue</value>
      </parameters>
    </component>
  </components>
</castle>

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

1 голос
/ 19 декабря 2008

Вы не можете настроить это только из одного XML. Но вы можете использовать фабрику , чтобы сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...