IoC - 多个实现支持单个接口

Bal*_*ala 17 c# castle-windsor ioc-container inversion-of-control

我想知道为什么.Net IoC容器不能轻易支持单个接口的多个实现!可能是我错了,但就我所见,像Ninject这样的框架部分支持使用注释这个功能(如何?).我不认为像Windsor或简单注入器这样的其他框架有一个简单的机制来支持这种情况.

是否有任何理由不支持许多框架?AFAIK,使用接口的最重要原因之一是实现松散耦合.如果框架旨在改善松散耦合,不能流利地支持单个接口的多个实现,我不明白为什么!

PS当然我理解在运行时会出现解决问题,容器会混淆选择哪种实现,但这是设计中必须考虑的事情,对吧?

GSe*_*rjo 10

Unity具有相同的功能

注册命名依赖项

    var container = new UnityContainer();
    container.RegisterType<IConnector, Connector>("TestConnector");
Run Code Online (Sandbox Code Playgroud)

按名称解析

    container.Resolve<IConnector>("TestConnector");
Run Code Online (Sandbox Code Playgroud)

同样的方法

    [Dependency("TestConnector")]
    public IConnector Connector { get; set; }
Run Code Online (Sandbox Code Playgroud)

温莎也一样

class Program
{
    static void Main(string[] args)
    {
        var container = new WindsorContainer()
            .Register(Component.For<IConnector>().ImplementedBy<ConnectorA>().Named("ConnectorA"))
            .Register(Component.For<IConnector>().ImplementedBy<ConnectorB>().Named("ConnectorB"));

        var connectorA = container.Resolve<IConnector>("ConnectorA");
        Console.WriteLine("Connector type: {0}", connectorA.GetType());
        var connectorB = container.Resolve<IConnector>("ConnectorB");
        Console.WriteLine("Connector type: {0}", connectorB.GetType());
        Console.ReadKey();
    }
}

public interface IConnector
{
}

public class ConnectorA : IConnector
{

}

public class ConnectorB : IConnector
{

}
Run Code Online (Sandbox Code Playgroud)


Aki*_*kim 7

我建议查看约定优于配置,特别是基于约定的依赖注入基于上下文的依赖注入.大多数IoC(如果不是全部)都支持这两种方法.当几个实现绑定到一个接口时,您可以找到许多具有不同IoC库的有趣示例,以及它可能有多大用处.

例如,支持绑定一个接口的几个实现:依赖于上下文或属性,按名称等等.

按上下文

以下片段绑定实现取决于目标类型自动:

Bind<IWarrior>().To<Samurai>().WhenInjectedInto(typeof(OnLandAttack));
Bind<IWarrior>().To<SpecialNinja>().WhenInjectedInto(typeof(AmphibiousAttack));
Run Code Online (Sandbox Code Playgroud)

按名字

配置在XML或数据库中时非常有用.InNamedScope还要考虑到:

Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");
Run Code Online (Sandbox Code Playgroud)

通过约定

在项目的不同部分使用不同的依赖关系配置.


Phi*_*rdt 6

你的前提是错的.

温莎非常高兴地接受同一服务的多个实现的注册.除了GSerjo在Windsor中提到的命名组件解析支持(默认情况下),第一个注册的实现将获胜但您可以IsDefault()在注册替代实现时通过使用方法来覆盖它.有关详细信息,请参阅http://docs.castleproject.org/Windsor.Registering-components-one-by-one.ashx.

如果您希望对多个实现中的选择进行更多控制,可以创建一个IHandlerSelector实现来执行此操作.有关更多详细信息,请参阅http://stw.castleproject.org/Windsor.Handler-Selectors.ashx.


man*_*lds 1

StructureMap 提供以下功能:

For<IMyInterface>().Add<MyInterfaceImpl1>().Named("MyInterfaceImpl1");
For<IUsingInterface>().Add<UsingInterfaceImpl>().Ctor<IMyInterface>().Is(i => i.GetInstance<IMyInterface>("MyInterfaceImpl1"));
Run Code Online (Sandbox Code Playgroud)