В настоящее время я просматриваю блок приложений Microsoft Unity, чтобы использовать его в одном из моих личных проектов. Я прочитал несколько статей и руководств об этом, но у меня есть вопрос об этом.
В этом примере о структуре они используют Unity для создания объекта, который наследует интерфейс IVehicle
. Те 3 класса, которые наследуют от него, не имеют никаких свойств, которые должны быть инициализированы в конструкторе, поэтому все работает хорошо.
Очевидно, что в моем проекте это не всегда так. У меня будут некоторые классы, для которых требуется инициализация свойства (или поля) в конструкторе. Мой вопрос: как мне это достичь? Или это то, что Единство не может сделать само по себе; Мне нужно было бы создать объект с помощью функции Unity Resolve()
, которая предоставила бы мне объект с неинициализированными полями/свойствами, а затем мне пришлось бы вызывать сеттер по очереди на каждое поле/свойства?
Unity поддерживает автоматическую проводку, которая позволяет вам решать сложные графические объекты, а не отдельные объекты.
Например, предположим, что у вас есть класс Car
реализующий ICar
который зависит от другого класса IEngine
с использованием IEngine
конструктора (для конструктора Car's требуется параметр типа IEngine).
public interface ICar
{
void Accelerate();
}
public interface IEngine
{
void Accelerate();
}
public class Car: ICar
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}
public void Accelerate()
{
_engine.Accelerate();
}
}
public class Engine: IEngine
{
public Engine()
{
}
public string Message {get; set;}
public void Accelerate()
{
Console.WriteLine("Accelerating." + Message);
}
}
Затем вы зарегистрируетесь в Unity, как разрешить ICar
и IEngine
:
var _container = new UnityContainer()
.RegisterType<ICar,Car>()
.RegisterType<IEngine,Engine>(
new InjectionProperty("Message", "Hello world"));
Затем, когда вы ICar
Unity сможет предоставить экземпляр Engine
для конструктора Car
, автоматически подключая зависимость, которую Car имеет на IEngine. Это также верно для любых дополнительных зависимостей, которые могут иметь Car
или Engine
, и любых свойств, зарегистрированных для инъекций.
var car = _container.Resolve<Car>();
car.Accelerate();
Ускорение. Мировой мир
Таким образом, разрешив ICar
Unity, вы получите полный граф объектов. Вы можете попробовать образец в этой скрипке
РЕДАКТИРОВАТЬ
Вы можете зарегистрировать тип, подлежащий разрешению, используя метод лямбда, который будет выполняться во время выполнения, например:
public interface IFoo
{
DateTime ResolvedTime {get; set;}
}
public class Foo: IFoo
{
public DateTime ResolvedTime {get; set;}
}
//Can be registered using a lambda as in:
container.RegisterType<IFoo,Foo>(
new InjectionFactory(c => new Foo{ ResolvedTime = DateTime.Now }));
Вы можете получить информацию о msdn. Я также обновил скрипку выше этим примером лямбда.
Engine
понадобилосьMessage
которое я мог предоставить только позже, во время разрешения, и я не знал этоMessage
во время регистрации в начале моего приложения? Unity кажется мне очень ограниченным в том смысле, что вы должны предоставить все параметры конструкторам, всем свойствам и т. Д. В самом начале вашего приложения, когда вы регистрируете свои объекты. Если я что-то еще не пропустил?ICarFactory
чтобы некоторый класс мог зависеть от этой фабрики и вызывать что-то вроде carFactory.CreateCar () вместо прямой зависимости отICar