2015-03-26 1 views
0

Я новичок в Unity, и у меня возникают проблемы с разрешением правильного объекта.Как выбрать зарегистрированный зависимый тип во время выполнения с помощью Unity IoC?

У меня есть класс CustomerManager, который принимает, как IDataAccess зависимости.

CustomerManager

public class CustomerManager 
{ 
    private IDataAccess dataAccess; 

    public CustomerManager(IDataAccess dataAccess) 
    { 
     this.dataAccess = dataAccess; 
    } 

    public Customer GetCustomer(int id) 
    { 
     return this.dataAccess.GetCustomer(id); 
    } 

    public void SaveCustomer(Customer customer) 
    { 
     this.dataAccess.SaveCustomer(customer); 
    } 
} 

IDataAccess

public interface IDataAccess 
{ 
    void SaveCustomer(Customer customer); 
    Customer GetCustomer(int id); 
} 

У меня есть 2 классов, которые реализуют IDataAccess называется SQLServerDataAccess и MongoDataAccess.

Что я пытаюсь сделать, это зарегистрировать классы, реализующие IDataAccess, а затем использовать Resolve для создания экземпляра CustomerManager.

Вот мой регистр:

UnityIoC.Instance.RegisterType<IDataAccess,SQLServerDataAccess>("SQL"); 
UnityIoC.Instance.RegisterType<IDataAccess,MongoDataAccess>("Mongo"); 

Когда я пытаюсь решить экземпляр классов IDataAccess непосредственно он работает отлично.

IDataAccess dataAccess = UnityIoC.Instance.Resolve<IDataAccess>("Mongo"); 

Однако, когда я пытаюсь решить CustomerManager, я получаю исключение.

Я делаю это:

CustomerManager manager = UnityIoC.Instance.Resolve<CustomerManager>(); 

Я получаю следующее исключение:

Resolution of the dependency failed, type = "UnityIoCExample.CustomerManager", name = "(none)". 

Exception occurred while: while resolving. 

Exception is: InvalidOperationException - The current type, UnityIoCExample.IDataAccess, is an interface and cannot be constructed. Are you missing a type mapping? 

----------------------------------------------- 

At the time of the exception, the container was: 
Resolving UnityIoCExample.CustomerManager,(none) 

Resolving parameter "dataAccess" of constructor UnityIoCExample.CustomerManager(UnityIoCExample.IDataAccess dataAccess) 

Resolving UnityIoCExample.IDataAccess,(none) 

Это для меня ясно, что исключение вызвано единства не зная, что зарегистрированный тип IDataAccess использовать как зависимость от CustomerManager, но я не могу понять, как это указать. Я делаю это в основном правильно и просто отсутствует одна часть, или я в отъезде?

Моя единственная мысль - использовать ParameterOverride при разрешении CustomerManager и разрешить IDataAccess внутри CustomerManager с использованием этого параметра.

Модифицированный CustomerManager конструктор:

public CustomerManager(string dbType) 
{ 
    this.dataAccess = UnityIoC.Instance.Resolve<IDataAccess>(dbType); 
} 

Для решения CustomerManager

CustomerManager manager = UnityIoC.Instance.Resolve<CustomerManager>(new ParameterOverride("dbType", "Mongo")); 

Я не уверен, что это действительно лучшая практика.

+0

Образец того, как вы хотите, чтобы полученный в результате код выглядел, может помочь. То есть если вы хотите, чтобы Unity «волшебным образом» выбрал класс, который вам нужен, вам нужно зарегистрировать этот интерфейс с пустым именем и каким-то образом выбрать один из вызовов «Resolve » («Mongo»). –

+0

Я в основном хочу этого: UnityIoC.Instance.RegisterType ("SQL"); UnityIoC.Instance.RegisterType ("Mongo"); CustomerManager manager = UnityIoC.Instance.Resolve (); Очевидно, мне нужно сообщить Resolve (), который IDataAccess использовать для решения CustomerManager. Мне не хватает этой части. – James

ответ

2

В описанном вами сценарии вам необходимо использовать InjectionContructor.

UnityIoC.Instance.RegisterType<IDataAccess,SQLServerDataAccess>("SQL"); 
UnityIoC.Instance.RegisterType<IDataAccess,MongoDataAccess>("Mongo"); 

UnityIoC.Instance.RegisterType<CustomerManager,CustomerManager>("Mongo", new InjectionConstructor(new ResolvedParameter<IDataAccess>("Mongo"))); 

UnityIoC.Instance.RegisterType<CustomerManager,CustomerManager>("SQL", new InjectionConstructor(new ResolvedParameter<IDataAccess>("SQL"))); 

CustomerManager manager = UnityIoC.Instance.Resolve<CustomerManager>(); 

Чтобы сохранить этот класс аккуратным некоторые его раз лучше, чтобы извлечь его из в DIConfig класса самостоятельно. некоторые из этих InjectionConstructors будут повторно использоваться, и извлечение в классе поможет с этим.

+0

Это было сделано. Я пытался что-то подобное, но просто не мог понять. Спасибо. Да, если бы это был настоящий проект, у меня было бы все, что было бы лучше организовано. Это просто главное приложение консоли. Сейчас я изучаю Единство. – James

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