Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuring Castle Windsor using xml/app.config

I am currently building a sample application using Castle Windsor. The motto is to use xml/app.config to switch method interception on/off. I had used the Fluent API earlier and it worked as a charm. As the next step, I am trying to replace the fluent API with my xml.

The gist of the code is as follows: A class called RandomOperations with two virtual methods. A LoggingAspect class which implements IInterceptor. A MyInterceptorsSelector class which implements IModelInterceptorsSelector A Program.cs which had the fluent api syntax earlier and is now uses to only make calls to methods of RandomOperations class. An app.config with a section called which has the xml syntax of registering components.

When I use the fluent api, I am able to intercept the method calls but I am unable to do it using the xml/app.config registration. Could someone please throw some light on what is being missed?

The classes are as follows:

RandomOperations.cs

public class RandomOperations 
    {
        public virtual int MyRandomMethod(int x)
        {
            return x * x;
        }

        public virtual void Writer(string x)
        {
            Console.WriteLine(x);
        }
    }

LoggingAspect.cs

public class LoggingAspect : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("Intercepted the call to " + invocation.Method.Name);
            invocation.Proceed();
            Console.WriteLine("After the method call, the return value is " + invocation.ReturnValue);
        }
    }

MyInterceptorsSelector.cs

public class MyInterceptorsSelector : IModelInterceptorsSelector
    {

        public bool HasInterceptors(ComponentModel model)
        {
            return typeof(LoggingAspect) != model.Implementation &&
                model.Implementation.Namespace.StartsWith("ConsoleApplication1") ;
        }

        public InterceptorReference[] SelectInterceptors(ComponentModel model, Castle.Core.InterceptorReference[] obj)
        {
            var interceptors = new List<InterceptorReference>(model.Interceptors.Count + 1);
            foreach (InterceptorReference inter in model.Interceptors)
            {
                interceptors.Add(inter);
            }

            return interceptors.ToArray();

        }
    }

Main in Program.cs

static void Main(string[] args)
        {
            var container = new WindsorContainer();
            //container.Register(Component.For<RandomOperations>().Interceptors(typeof(LoggingAspect)));
            //container.Register(Component.For<LoggingAspect>());
            //container.Kernel.ProxyFactory.AddInterceptorSelector(new MyInterceptorsSelector());
            var service = container.Resolve<RandomOperations>();
            service.MyRandomMethod(4);
            service.Writer("Hello, World");
        }

Removing the commented out fluent api syntax makes the application work correctly.

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
  </configSections>

  <castle>
    <components>

      <component id="MyInterceptorsSelector" type="MyInterceptorsSelector"/>
      <component
        id="LoggingAspect"
        type="ConsoleApplication1.LoggingAspect, ConsoleApplication1">
      </component>
      <component
        type="ConsoleApplication1.RandomOperations, ConsoleApplication1">
        <interceptors selector="${MyInterceptorsSelector}">
          <interceptor>${LoggingAspect}</interceptor>
        </interceptors>
      </component>

    </components>
  </castle>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>

</configuration>

Thanks in advance.

like image 244
user2930995 Avatar asked Aug 03 '15 09:08

user2930995


1 Answers

You need to pass an IConfigurationInterpreter to your Windsor constructor. Change:

var container = new WindsorContainer();

To:

var container = new WindsorContainer(new XmlInterpreter());

The XmlInterpreter (with no parameters) will pull configuration from your app.config/web.config.

For more options on using IConfigurationInterpreter, see the docs.

like image 142
PatrickSteele Avatar answered Nov 02 '22 17:11

PatrickSteele