使用依赖性解析器

时间:2016-08-12 10:10:37

标签: asp.net-mvc castle-windsor

我注意到当我通过命名覆盖注册我的依赖项时,依赖性解析器努力正确地解析组件。似乎提供了第一个实例。 ctor注射一切都很好。

示例:

注册

RegisterProvider<IAccountProvider, AccountProvider>();
RegisterProvider<IAccountProvider, CustomAccountProvider>("customAccountProvider");

解决

var instance = DependecyResolver.Current.GetService<IAccountProvider>();

无法检索 customAccountProvider 实例。 它总是引用忽略命名约束的第一个注册组件。

1 个答案:

答案 0 :(得分:0)

如果您有多个相同组件的实现,则必须为其命名或使用标记界面标记它们。这是一个命名实例的代码示例:

using System;
using System.Linq;
using System.Reflection;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace ResolvingNamedInctances
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new WindsorContainer();
            container.AddFacility<TypedFactoryFacility>();

            container.Register(Component.For<ITypedFactoryComponentSelector>().ImplementedBy<AccountProviderTypeSelector>());
            container.Register(Component.For<IAccountProviderSelector>().AsFactory(typeof(AccountProviderTypeSelector)));


            container.Register(Component.For<IAccountProvider>().ImplementedBy<DefaultAccountProvider>().Named("default"));
            container.Register(Component.For<IAccountProvider>().ImplementedBy<CustomAccountProvider>().Named("custom"));

            // uncomment this line in MVC app and use DependencyResolver instead of container
            //DependencyResolver.SetResolver(new WindsorDependencyResolver(container.Kernel));

            var accountProviderSelector = container.Resolve<IAccountProviderSelector>();

            var defaultAccountProvider = accountProviderSelector.GetAccountProvider(); // default
            defaultAccountProvider.Provide();


            var customAccountProvider = accountProviderSelector.GetAccountProvider("custom");
            customAccountProvider.Provide();

            Console.ReadLine();
        }
    }

    public class AccountProviderTypeSelector : ITypedFactoryComponentSelector
    {
        public Func<IKernelInternal, IReleasePolicy, object> SelectComponent(MethodInfo method, Type type, object[] arguments)
        {

            string providerName = arguments.Length > 0 ? (string)arguments[0] : "default";
            return (k, r) => k.GetHandlers(typeof(IAccountProvider))
                .Where(
                    h =>
                    {

                        return h.ComponentModel.Name == providerName;
                    })
                .Select(h => (IAccountProvider)k.Resolve(
                    h.ComponentModel.Name,
                    typeof(IAccountProvider),
                    new Arguments { },
                    r))
            .FirstOrDefault();
        }
    }

    public interface IAccountProviderSelector
    {
        IAccountProvider GetAccountProvider();
        IAccountProvider GetAccountProvider(string nameIdentifier);
    }

    public interface IAccountProvider
    {
        void Provide();
    }

    public class DefaultAccountProvider : IAccountProvider
    {
        public void Provide()
        {
            Console.WriteLine("Working in default AccountProvider");
        }
    }

    public class CustomAccountProvider : IAccountProvider
    {
        public void Provide()
        {
            Console.WriteLine("Working in standart CustomAccountProvider");
        }
    }
}