Search code examples
c#web-configcastle-windsor

Castle Windsor web.config parameters


I would transfer the Windor installer in the web.config of my webapplication, but I need to pass a parameter that is a static attribute of a class. There's an example:

// (namespace Web)

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
        Component.For(typeof(IRepository))
            .ImplementedBy(typeof(Repository<MyCtx>))
            .DependsOn(Dependency.OnValue("store", MvcApplication.GlobalStore))
            .LifestylePerWebRequest()
    );
}

My actual web.config:

<components>
  <component
      service="Core.Business.IRepository, Core"
      type="EF.Business.Repository, EF"
      lifestyle="PerWebRequest">
    <parameters>
      <store>Web.MvcAppltication.GlobalStore ???</store>
    </parameters>
  </component>
</components>

Solution

  • I concluded that something has to be defined in the code. Therefore I decided the way of create a facility.

    My new code:

    Web.config

     <component
          service="Core.Business.IRepository, Core"
          type="EF.Business.Repository`1[[EF.CreationContext, EF]], EF"
          lifestyle="PerWebRequest">
      </component>
    

    DependencyResolver.cs

    public class RuntimeDataSupportFacility : AbstractFacility
    {
        protected override void Init()
        {
            Kernel.Resolver.AddSubResolver(new RuntimeDataDependencyResolver());
        }
    }
    
    public class RuntimeDataDependencyResolver : ISubDependencyResolver
    {
        private Type[] acceptedTypes = new[] { typeof(IDictionary<String, Object>) };
    
        public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
        {
            if (ReferenceEquals(dependency.TargetType, acceptedTypes[0])) // typeof(IDictionary<String, Object>
                return MvcApplication.GlobalStore;
    
            return null;
        }
    
        public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
        {
            if (acceptedTypes.Any(t => ReferenceEquals(t, dependency.TargetType)))
                return true;
    
            return false;
        }
    }
    

    And on Global.asax.Application_Start():

    Container =
        new WindsorContainer()
        .AddFacility<RuntimeDataSupportFacility>() // New code
        .Install(Configuration.FromAppConfig());