Asp.net mvc 使用依赖项解析程序解析命名依赖项

Asp.net mvc 使用依赖项解析程序解析命名依赖项,asp.net-mvc,castle-windsor,Asp.net Mvc,Castle Windsor,我注意到,当我通过命名覆盖注册依赖项时,依赖项解析器很难正确解析组件。似乎提供了第一个实例。注射后一切正常 例如: 登记 RegisterProvider(); 注册提供者(“customAccountProvider”); 决议 var instance=dependcysolver.Current.GetService(); 无法检索customAccountProvider实例。 它总是指忽略命名约束的第一个注册组件。当同一组件有多个实现时,必须命名它们或使用标记接口标记它们。下面是一

我注意到,当我通过命名覆盖注册依赖项时,依赖项解析器很难正确解析组件。似乎提供了第一个实例。注射后一切正常

例如:

登记

RegisterProvider();
注册提供者(“customAccountProvider”);
决议

var instance=dependcysolver.Current.GetService();
无法检索customAccountProvider实例。
它总是指忽略命名约束的第一个注册组件。

当同一组件有多个实现时,必须命名它们或使用标记接口标记它们。下面是一个命名实例的代码示例:

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");
        }
    }
}
使用系统;
使用System.Linq;
运用系统反思;
使用Castle.Facilities.TypedFactory;
使用Castle.MicroKernel;
使用Castle.MicroKernel.Registration;
使用温莎城堡;
名称空间解析NamedInctances
{
班级计划
{
静态void Main(字符串[]参数)
{
var container=新的WindsorContainer();
container.AddFacility();
container.Register(Component.For().ImplementedBy());
container.Register(Component.For().AsFactory(typeof(AccountProviderTypeSelector));
container.Register(Component.For().ImplementedBy().Named(“default”));
container.Register(Component.For().ImplementedBy().Named(“custom”));
//在MVC应用程序中取消对此行的注释,并使用DependencyResolver而不是容器
//SetResolver(新的WindsorDependencyResolver(container.Kernel));
var accountProviderSelector=container.Resolve();
var defaultAccountProvider=accountProviderSelector.GetAccountProvider();//默认值
defaultAccountProvider.Provider();
var customAccountProvider=accountProviderSelector.GetAccountProvider(“自定义”);
customAccountProvider.Provider();
Console.ReadLine();
}
}
公共类AccountProviderTypeSelector:ITypedFactoryComponentSelector
{
public Func SelectComponent(MethodInfo方法、类型、对象[]参数)
{
字符串提供程序名称=参数。长度>0?(字符串)参数[0]:“默认值”;
return(k,r)=>k.GetHandlers(typeof(IAccountProvider))
.在哪里(
h=>
{
返回h.ComponentModel.Name==providerName;
})
.选择(h=>(IAccountProvider)k.Resolve(
h、 ComponentModel.Name,
类型(IAccountProvider),
新参数{},
r) )
.FirstOrDefault();
}
}
公共接口IAccountProviderSelector
{
IAccountProvider GetAccountProvider();
IAccountProvider GetAccountProvider(字符串名称标识符);
}
公共接口提供程序
{
无效提供();
}
公共类DefaultAccountProvider:IAccountProvider
{
公共图书馆
{
Console.WriteLine(“在默认AccountProvider中工作”);
}
}
公共类CustomAccountProvider:IAccountProvider
{
公共图书馆
{
Console.WriteLine(“在standart CustomAccountProvider中工作”);
}
}
}

当您有同一组件的多个实现时,您必须命名它们或使用标记接口标记它们。下面是一个命名实例的代码示例:

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");
        }
    }
}
使用系统;
使用System.Linq;
运用系统反思;
使用Castle.Facilities.TypedFactory;
使用Castle.MicroKernel;
使用Castle.MicroKernel.Registration;
使用温莎城堡;
名称空间解析NamedInctances
{
班级计划
{
静态void Main(字符串[]参数)
{
var container=新的WindsorContainer();
container.AddFacility();
container.Register(Component.For().ImplementedBy());
container.Register(Component.For().AsFactory(typeof(AccountProviderTypeSelector));
container.Register(Component.For().ImplementedBy().Named(“default”));
container.Register(Component.For().ImplementedBy().Named(“custom”));
//在MVC应用程序中取消对此行的注释,并使用DependencyResolver而不是容器
//SetResolver(新的WindsorDependencyResolver(container.Kernel));
var accountProviderSelector=container.Resolve();
var defaultAccountProvider=accountProviderSelector.GetAccountProvider();//默认值
defaultAccountProvider.Provider();
var customAccountProvider=accountProviderSelector.GetAccountProvider(“自定义”);
customAccountProvider.Provider();
Console.ReadLine();
}
}
公共类AccountProviderTypeSelector:ITypedFactoryComponentSelector
{
public Func SelectComponent(MethodInfo方法、类型、对象[]参数)
{
字符串提供程序名称=参数。长度>0?(字符串)参数[0]:“默认值”;
return(k,r)=>k.GetHandlers(typeof(IAccountProvider))
.在哪里(
h=>
{
返回h.ComponentModel.Name==providerName;
})
.选择(h=>(IAccountProvider)k.Resolve(
h、 ComponentModel.Name,
类型(IAccountProvider),
新参数{},
r) )
.FirstOrDefault();
}
}
公共接口IAccountProviderSelector
{
IAccountProvider GetAccountProvider();
IAccountProvider GetAccountProvider(字符串名称标识符);
}
公共接口提供程序
{
无效提供();
}
公共类
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");
        }
    }
}