2012-02-17 5 views
0

Я пытаюсь использовать атрибут Dependency с использованием RegisterInstance. Я читал, что если я использую RegisterInstance, я должен использовать метод BuildUp для экземпляра. К сожалению, это не работает в моем коде. Он не разрешает Alarm. Когда я использую свой код без RegisterInstance, все в порядке, но мне нужно использовать RegisterInstance. Я что-то пропустил?BuildUp не разрешает зависимость

EDIT

var container = new UnityContainer(); 
container.RegisterType<IAlarm, Alarm>(); 

ICar car = new Car(); 
container.RegisterInstance<ICar>(car); 
var carFromContainer = container.BuildUp<ICar>(container.Resolve<ICar>()); 
var alarm = carFromContainer.Alarm; 

public interface ICar 
{ 
    IAlarm Alarm { get; set; } 
} 

public class Car : ICar 
{ 
    private IAlarm _alarm; 

    [Dependency] 
    public IAlarm Alarm 
    { 
     get { return _alarm; } 
     set { _alarm = value; } 
    } 
} 

public interface IAlarm 
{ 
    void Launch(); 
} 

public class Alarm : IAlarm 
{ 
    public void Launch() 
    { 
     Console.WriteLine("Alarm !"); 
    } 
} 

Старый пример

var container = new UnityContainer(); 
container.RegisterType<IAlarm, Alarm>(); 
ICar car = new Car(); 
container.RegisterInstance<ICar>(car); 

//container.RegisterType<ICar, Car>(); 

var client = new Client(container); 
var alarm = client.Car.Alarm; 
client.Car.Alarm.Launch(); 

public class Client 
{ 
    public ICar Car { get; set; } 
    public Client(UnityContainer container) 
    { 
     //Car = container.Resolve<ICar>(); 
     Car = container.BuildUp<ICar>(container.Resolve<ICar>()); 
    } 
} 


public interface ICar 
{ 
    IAlarm Alarm { get; set; } 
} 

public class Car : ICar 
{ 
    private IAlarm _alarm; 

    [Dependency] 
    public IAlarm Alarm 
    { 
     get { return _alarm; } 
     set { _alarm = value; } 
    } 
} 

public interface IAlarm 
{ 
    void Launch(); 
} 

public class Alarm : IAlarm 
{ 
    public void Launch() 
    { 
     Console.WriteLine("Alarm !"); 
    } 
} 

ответ

2

Я не понимаю ваш пример кода. Вы новичок в Car и зарегистрируете его в контейнере. Затем вы указываете контейнеру на карте IAlarm классу реализации Alarm. Затем вы вводите контейнер в ваш Client, который сильно разочарован. Контейнеры DI никогда не должны упоминаться за пределами Composition root вашего приложения. И затем вы (ab) используете свой контейнер как ServiceLocator (который считается anti-pattern in modern application architecture), чтобы разрешить ICar и вставить некоторое значение в свойство.

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


UPDATE

Изменить определение интерфейса для ICar и поставить DependencyAttribute там, и это работает.

Но я не могу рекомендовать этот подход. DI attributes should not polute your code.

+0

Себастьян, вы абсолютно правы. Я с тобой согласен. Но это только пример, насколько это возможно. В моем реальном приложении я следую хорошей практике, которую вы указали. Я редактировал свой пост, чтобы дать более ясный пример. – user278618

+0

@ user278618 Я обновил свой ответ –

+0

отлично, он работает :), но ваша ссылка лучше. – user278618

Смежные вопросы