Unity - 为同一个接口注入不同的类

时间:2012-10-29 22:33:03

标签: c# inversion-of-control unity-container

我有一个界面:IFoo
实现该界面的两个类:FooOneFooTwo
并且两个类ClassOneClassTwo在构造函数中接收IFoo参数。

我如何配置统一,以便ClassOne收到FooOne个实例,ClassTwo仅使用一个容器收到FooTwo

我不能在运行时这样做,所以它必须在配置文件中。

3 个答案:

答案 0 :(得分:18)

查看Unity documentation

对于更易读的配置文件,您应该为IFooFooOneFooTwoClassOneClassTwo定义类型别名。然后,您需要将IFoo中的映射注册到您的实现。您需要为映射设置name。 对于IFoo的消费者,您需要注册InjectionConstructor

您的配置将如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
      Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="IFoo" type="UnityConfigFile.IFoo, UnityConfigFile" />
    <alias alias="FooOne" type="UnityConfigFile.FooOne, UnityConfigFile" />
    <alias alias="FooTwo" type="UnityConfigFile.FooTwo, UnityConfigFile" />
    <alias alias="ClassOne" type="UnityConfigFile.ClassOne, UnityConfigFile" />
    <alias alias="ClassTwo" type="UnityConfigFile.ClassTwo, UnityConfigFile" />
    <container>
      <register type="IFoo" name="1" mapTo="FooOne" />
      <register type="IFoo" name="2" mapTo="FooTwo" />
      <register type="ClassOne" mapTo="ClassOne">
        <constructor>
          <param name="foo">
            <dependency type="IFoo" name="1" />
          </param>
        </constructor>
      </register>
      <register type="ClassTwo" mapTo="ClassTwo">
        <constructor>
          <param name="foo">
            <dependency type="IFoo" name="2" />
          </param>
        </constructor>
      </register>
    </container>
  </unity>
</configuration>

这是相应的测试,显示它是如何工作的。

UnityConfigurationSection config =
  (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
IUnityContainer container = new UnityContainer();
container.LoadConfiguration(config);
ClassTwo two = container.Resolve<ClassTwo>();
Assert.IsInstanceOfType(two.Foo, typeof(FooTwo));

<强>更新

在运行时,你可以这样做

IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, FooOne>("One");
container.RegisterType<IFoo, FooTwo>("Two");
container.RegisterType<ClassOne>(new InjectionConstructor(
  new ResolvedParameter<IFoo>("One")));
container.RegisterType<ClassTwo>(new InjectionConstructor(
  new ResolvedParameter<IFoo>("Two")));

答案 1 :(得分:3)

您需要为他们提供注册名称:

// Create an instance of a service you want to use. Alternatively, this
// may have been created by another process and passed to your application
LoggingService myLoggingService = new LoggingService();

// Register the existing object instance with the container
container.RegisterInstance<IMyService>("Logging", myLoggingService);

// Register a mapping for another service your application will use
container.RegisterType<IMyService, myDataService>("DataService");

// When required, retrieve an instance of these services
IMyService theDataService = container.Resolve<IMyService>("DataService");
IMyService theLoggingService = container.Resolve<IMyService>("Logging");

取自Resolving Instances Of Types Using Unity

答案 2 :(得分:0)

我在我的应用程序中设置了这样的

已安装的Nuget Package Unity版本4.0.1

export default class Test extends Component {

    constructor(props) {
        super();
        this.subscription = 0;
        this.state = {
        };
        changePage = props.cb;
        console.log("props", props);


      render(){

        return (
            <Container  ref="park-places-ref">

                <View style={styles.viewmain}>

                <View style={styles.viewborder}>

                </View>

          fetch('https://online.ssm.it/php/mobile/parkinfo') // Call the fetch function passing the url of the API as a parameter
          .then((response) => response.json()) // Transform the data into json
            data={response.body}
          })
            .catch(function() {
                // This is where you run code if the server returns any errors
            });

                <FlatList
                ItemSeparatorComponent={ () => <View style={ styles.rowSep } /> }

                Mydata={data}


                renderItem={

                    ({item}) => (
                    <View style={styles.row}>
                        <View style={styles.circle}   backgroundColor= {item.color}/>
                        <View style={styles.column}>
                            <Text style={styles.itemBold}>{item.extensioname}</Text>
                            <Text style={styles.itemNormal}>{item.free}</Text>

                            <Text style={styles.itemBold}>{item.freeplaces}</Text>


                        </View>
                    </View>
                    )
                }
                keyExtractor={item => item.extensioname}
                />
                </View>


            </Container>
        );
    }
}

在我的App.config

<package id="Unity" version="4.0.1" targetFramework="net452" />

在我的App.xaml.cs

<configSections>
     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>

<unity>
    <container>
        <register type="MyApp.MainWindow, MyApp">
            <lifetime type="singleton" />
        </register>
        <register name="UnityResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.UnityResolver, Avelyn.Core" />
        <register name="NinjectResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.NinjectResolver, Avelyn.Core" />
    </container>
</unity>