Единство зарегистрировать экземпляр и решить - PullRequest
7 голосов
/ 05 февраля 2010

Я написал класс, который имеет некоторые зависимости, которые он разрешает из контейнера Unity.

Из моего основного класса я создаю новый объект

MyObject myObject = new MyObject();

Я регистрирую его в своем Unity Container

UContainer.RegisterInstance<MyObject>(myObject, new ExternallyControlledLifetimeManager());

Я создаю тип, который нуждается в этом в качестве зависимости

ConsumerObject consumer = new ConsumerObject();

потребитель выглядит так:

public class ConsumerObject
{
    public ConsumberObject()
    {
         theObject = (MyObject)UContainer.Resolve(typeof(MyObject));    
    }
}

это вызывает исключение:

Не удалось разрешить зависимость, type = "MyObject", name = "". Сообщение об исключении: текущая операция сборки (ключ сборки [Build Key [MyObject, null])) не выполнена: параметр pp не может быть разрешен при попытке вызвать конструктор MyObject (IPreferenceStorageProvider pp). (Тип стратегии BuildPlanStrategy, индекс 3)

Почему мой решающий вызов пытается вызвать другого типа constructor? Я уже создал его и зарегистрировал экземпляр .. Я также попробовал его так: theObject = UContainer.Resolve<MyObject>();, кажется, не имеет никакого значения ..

Спасибо

Ответы [ 4 ]

10 голосов
/ 24 декабря 2010

Я думаю, что проблема в том, что вы используете ExternallyControlledLifetimeManager. В этом случае контейнер Unity содержит только слабую ссылку на ваш экземпляр. И когда вы пытаетесь решить, ваш экземпляр уже мусор собрал. Вот почему по умолчанию LifeTimeManager для .RegisterInstance () - это ContainerControlledLifeTimeManager. И дело Даррела Миллера это работает, потому что это еще не GC-ed. Попробуйте зарегистрировать свой экземпляр так:

UContainer.RegisterInstance<MyObject>(myObject);
3 голосов
/ 09 февраля 2010

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

Вы пробовали что-то подобное,

public class ConsumerObject
{
    public ConsumberObject(MyObject myObject)
    {
         theObject = myObject
    }
}

, а затем с помощью UContainer.Resolve<MyObject>()?

Единственное, о чем я могу думать, это когда вы получаете доступ к UContainer.RegisterInstance, а затем к UContainer.Resolve, что вы фактически получаете доступ к двум различным контейнерам. Не могли бы вы показать нам, как вы объявляете UContainer?

1 голос
/ 05 февраля 2010

Насколько я знаю, Unity пытается (по умолчанию) вызвать конструктор с наибольшим количеством параметров и пытается разрешить каждый из параметров из сопоставлений. Вы должны добавить отображение для IPreferenceStorageProvider или удалить конструктор, который требует этот параметр.

Если вы не хотите, чтобы параметр IPreferenceStorageProvider вводился с помощью единицы, возможно, его вообще не следует объявлять как параметр конструктора. Вы можете жестко создать экземпляр этого объекта в конструкторе по умолчанию.

0 голосов
/ 19 марта 2018

«MyObject» - это тип, который реализует интерфейс, который я предполагаю. Попробуйте зарегистрироваться с интерфейсом вместо фактической реализации.

что-то вроде:

UContainer.RegisterInstance<IMyObject>(myObject, new ExternallyControlledLifetimeManager());

Также, если у вас есть несколько реализаций одного и того же интерфейса, не забудьте назвать их при регистрации, если вы не хотите переопределить уже зарегистрированную реализацию.

Для получения дополнительной помощи, я предлагаю вам посетить MSDN:

https://msdn.microsoft.com/en-us/library/ff648449.aspx

...