我有第三方图书馆返回班级实例。它不在我的cotrol中,但我想用Unity
来影响它的公共属性。由于我不能将DependecyAttribute
添加到其属性中,因为该类不是部分的,也不是继承的,我想知道是否可以使用Unity
XML配置来执行操作。
是否可以使用Unity's
XML配置来配置构建依赖项?如果答案是肯定的。如何配置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)
答案 0 :(得分: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友好的课程来玩
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;
包装器实例化第三方对象的副本,然后将服务注入相应的属性(或者可以通过方法调用等传入)。
这不会占用太多代码,可以进行单元测试并满足您的需求。
答案 1 :(得分:1)
根据您发布的代码,应该没有问题。
我创建了两个项目:一个控制台应用程序和一个名为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!
。也许,确切的情况与您发布的(我假设是虚构的)示例或其他未正确配置的情况不同?