简体   繁体   中英

How to apply a Service Override implicitly (inline, when resolving) in Castle Windsor?

Consider the form using additional parameters to resolved components that "works". Note that it is okay if the root is Resolved here.

var c1a = container.Resolve<IC1>(new { v = "a" });
var c1b = container.Resolve<IC1>(new { v = "b" });
// Takes two different objects, of the same interface
var root = container.Resolve<C2>(new { c1a = c1a, c2a = c2a });

However I don't like it because 1. neither c1a not c2a will be "auto released" and 2. it feels too manual.

container.Release(c2);
container.Release(c1a);
container.Release(c1b);

What I would like to do is something like the following (which is invalid of course) that uses an implicit service override - note that there is only one direct Resolve and the objects should be created by CW internally.

var root = container.Resolve<C2>(new {
   c1a = InlineOverride.For<IC1>.With(new { v = "a" }),
   c2a = InlineOverride.For<IC1>.With(new { v = "a" })
});
container.Release(root); // Just one root

I have a feeling I am just missing the concept / application of Service Overrides which appear to only be supported explicitly during registration of the dependent (C2) component.

so just one way that i have handled something close to this, not sure if it will help out.

public class Tinker
{
    public interface ISomethingWithChar
    {
        char V { get; set; }
    }

    public class SomethingWithChar:ISomethingWithChar
    {
        public char V { get; set; }
    }

    public interface INeedTwoSomethingWithChars
    {
        ISomethingWithChar C1A { get; set; }
        ISomethingWithChar C2A { get; set; }
    }

    public class NeedTwoSomethingWithChars:INeedTwoSomethingWithChars
    {
        public ISomethingWithChar C1A { get; set; }
        public ISomethingWithChar C2A { get; set; }
    }

    public class Installers:IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
            Component
                .For<ISomethingWithChar>()
                .ImplementedBy<SomethingWithChar>()
                .Named("CharOne")
                .DynamicParameters((k,d) =>
                {
                    d["V"] = container.Resolve<IArgs>().CharOne;
                }),
            Component
                .For<ISomethingWithChar>()
                .ImplementedBy<SomethingWithChar>()
                .Named("CharTwo")
                .DynamicParameters((k, d) =>
                {
                    d["V"] = container.Resolve<IArgs>().CharTwo;
                }),
            Component
                .For<INeedTwoSomethingWithChars>()
                .ImplementedBy<NeedTwoSomethingWithChars>()
                .DependsOn(Parameter.ForKey("C1A").Eq("${CharOne}"), Parameter.ForKey("C2A").Eq("${CharTwo}")));
        }
    }


    public static void DoSomething(IArgs args)
    {
        using (var container = BootstrapContainer(args))
        {
            var needTwo = container.Resolve<INeedTwoSomethingWithChars>();
            Console.WriteLine("One: {0} and Two: {1}", needTwo.C1A.V, needTwo.C2A.V);
        }
    }

    private static IWindsorContainer BootstrapContainer(IArgs args)
    {
        var container = new WindsorContainer();
        container.Register(Component
            .For<IArgs>()
            .Instance(args));

        container.Install(FromAssembly.This());

        return container;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM