0

我有一个第三方库返回一个类实例。它超出了我的控制范围,但我想Unity在它的公共属性中使用它。DependecyAttribute由于该类既不是部分的也不是继承的,所以我不能添加到它的属性中,我想知道我是否可以使用UnityXML 配置来进行 inyection。

是否可以使用Unity'sXML 配置来配置构建依赖项?如果答案是肯定的。如何配置 XML 来做到这一点?

我试过了:

<register type="IService" mapTo="Service"> <!--Service has public constructor-->
</register>

<!--ThirdPartyObj has no interface and no public constructor-->
<register type="ThirdPartyObj " mapTo="ThirdPartyObj">
    <!-- Inject the property "Service" -->
    <property name="Service" /> //type of the property is IService
</register>

如果Unity Resolve ThidPartyObj购买不工作BuilUp(服务属性中的空引用)并且不能Resolve ThirdPartyObj因为没有公共构造函数,此配置将工作。

我想要归档的简单示例:

IUnityContainer uc = New UnityContainer() //create container
container.LoadConfiguration() // load from XML config
ThirdPartyObj foo = ThirdPartyLibrary.getFooInstace() //get third party instance
container.BuildUp(foo.getType, foo) //inyect dependencies
Console.WriteLine(foo.Service.getServiceMessage)
4

2 回答 2

1

为此创建一个对 Unity 友好的包装器:

public interface IThirdpartyWrapper
{
   ThirdpartyObj ConfiguredObject{get;}
}
public class ThirdpartyWrapper:IThirdpartyWrapper
{
    private ThirdpartyObject _thirdPartyObject;
     public ThirdpartyWrapper(IService myService)
    {
         _thirdPartyObject=ThirdPartyLibrary.getFooInstance();
         _thirdPartyObject.Service=myService;
    }
     public ThirdpartyObj ConfiguredObject
    {
      get{return _thirdPartyObject;}
    }

}

现在我们有一个对 Unity 友好的类可以玩

统一 XML 配置:

<register type="IService" mapTo="Service"> <!--Service has public constructor-->
</register>

<!--ThirdPartyObj has no interface and no public constructor-->
<register type="IThirdpartyWrapper" mapTo="IThirdpartyWrapper">
</register>

当我执行以下操作时:

var wrapper=_container.Resolve<IThirdpartyWrapper>();
var configuredObject=wrapper.ConfiguredObject;

包装器实例化第三方对象的副本,然后将服务注入适当的属性(或者可以通过方法调用等传入)。

这不需要太多代码,是可单元测试的,并且可以满足您的需求。

于 2013-07-31T11:47:51.900 回答
1

根据您发布的代码,应该没有问题。

我创建了 2 个项目:一个控制台应用程序和一个名为 ThirdPartyLibrary 的类库。

ThirdPartyLibrary 包含以下内容(从发布的代码推断):

namespace ThirdPartyLibrary
{
    public interface IService
    {
        string GetServiceMessage { get; }
    }

    public class Service : IService
    {
        public Service() { }

        public string GetServiceMessage
        {
            get { return "The message!"; }
        }
    }

    public static class ThirdPartyLibrary
    {
        public static ThirdPartyObj GetFooInstance()
        {
            return new ThirdPartyObj();
        }
    }

    public interface IThirdPartyObj { }
    public class ThirdPartyObj : IThirdPartyObj
    {
        internal ThirdPartyObj() { }
        public IService Service { get; set; }
    }
}

XML 配置如下所示:

<?xml version="1.0"?>
<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">

    <container>
      <register type="ThirdPartyLibrary.IService, ThirdPartyLibrary" mapTo="ThirdPartyLibrary.Service, ThirdPartyLibrary">
      </register>

      <register type="ThirdPartyLibrary.IThirdPartyObj, ThirdPartyLibrary" mapTo="ThirdPartyLibrary.ThirdPartyObj, ThirdPartyLibrary">
        <!-- Inject the property "Service" -->
        <property name="Service" />
      </register>
    </container>

  </unity>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

控制台应用程序是:

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer(); //create container
        container.LoadConfiguration(); // load from XML config
        ThirdPartyObj foo = ThirdPartyLibrary.ThirdPartyLibrary.GetFooInstance(); //get third party instance
        container.BuildUp(foo.GetType(), foo); //inyect dependencies
        Console.WriteLine(foo.Service.GetServiceMessage);
    }
}

这可以正常工作The message!并按预期输出。也许,确切的场景与您发布的(我假设是虚构的)示例不同,或者其他配置不正确?

于 2013-07-31T23:46:20.887 回答