2013-07-31 2 views
0

У меня есть сторонняя библиотека, возвращающая класс instace. Это из моего cotrol, но я хочу использовать Unity для inyect в его публичных объектах. Поскольку я не могу добавить DependecyAttribute к своим свойствам, потому что класс не является частичным и не наследуется, мне интересно, могу ли я использовать конфигурацию XML Unity, чтобы сделать inyection.Unity BuildUp without DependencyAttribute

Возможно ли использовать конфигурацию конфигурации Unity's для настройки зависимостей наращивания? Если да, то да. Как настроить 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 ResolveThidPartyObj купить не работает в BuilUp (Null ссылки в собственности Service) и не ResolveThirdPartyObj, потому что не имеет открытый конструктор может.

Простой пример того, что я хочу АРХИВ:

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) 

ответ

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!, как и ожидалось. Возможно, точный сценарий - это не то же самое, что и ваш опубликованный (я предполагаю, фиктивный) пример, или что-то еще не настроено правильно?

+0

Спасибо Tuzo! По крайней мере, у меня есть подтверждение, что я в правильном направлении. Должно быть, что-то не так хорошо confgiured, потому что я пытаюсь ваш пример и foo.Service является Null в моем отладчике. Это странно. Дайте мне некоторое время зашифровать ошибки в моей конфигурации, прежде чем я приму свой ответ. – jlvaquero

+0

Я только что создал новый проект, скопировавший мой код, и моя конфигурация и все в порядке. – jlvaquero

1

Создать оболочку для этого, что единство людей:

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 Config:

<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; 

Обертка конкретизирует копию объекта и третьей стороны затем впрыскивает службу в соответствующую собственность (или может быть передана с помощью вызова метода, и т.д.).

Это не займет много кода, проверяется на единицу и делает то, что вам нужно.

+0

Привет, спасибо за ответ, но то, что я хочу, это inyect Service в ThirdPartyObj, а не TridPartyObj в сервисе. Возьмите добычу в моей последней части кода, чтобы проверить, какой результат я хочу. – jlvaquero

+0

Исправлено. Перевернул DI, но он все равно применяется. Просто создайте обертку, которая делает DI недружественный код DI-friendly.В приведенном выше примере мы вводим экземпляр IService в оболочку и передаем его третьему объекту. –