Назначение блока приложений Unity в Microsoft Enterprise Library? - PullRequest
7 голосов
/ 11 ноября 2009

Может кто-нибудь объяснить мне, какова цель блока приложений Unity? Я попытался просмотреть документацию, но все это очень абстрактно.

Какие практические применения для блока Unity?

Ответы [ 2 ]

15 голосов
/ 11 ноября 2009

Инверсия управления

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

Microsoft Unity из группы Enterprise Patterns and Practices - это контейнерный проект Inversion of Control, или сокращенно IoC. Точно так же, как Castle Windsor, StructureMap и т. Д. Этот тип разработки также упоминается в терминах ламена как Свободное соединение ваших компонентов.

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

Например, вместо того, чтобы обращаться к статическим менеджерам (которые почти невозможно провести модульное тестирование), вы создаете объект, который зависит от внешней зависимости. Давайте возьмем почтовый сервис, в котором вы хотите получить доступ к БД для получения поста.

public class PostService : IPostService
{
  private IPostRepository _postRepo;

  public PostService(IPostRepository postRepo)
  {
    _postRepo = postRepo;
  }

  public IList<Post> GetPosts()
  {
    return _postRepo.GetAllPosts().ToList();
  }
}

Этот объект PostService теперь имеет внешнюю зависимость от IPostRepository. Заметьте, как не используются бетоны и классы статического менеджера? Вместо этого у вас есть слабая связь простого интерфейса - который дает вам возможность подключать все различные виды конкретных классов, которые реализуют IPostRepository.

Цель Microsoft Unity - автоматически подключить этот IPostRepository для вас. Так что вам никогда не придется беспокоиться о выполнении:

// you never have to do this with Unity
IPostRepository repo = new PostRepository();
IPostService service = new PostService(repo); // dependency injection
IList<Post> posts = service.GetPosts();

Выше показано, где вы должны реализовать два конкретных класса, PostRepository () и PostService (). Это тесно связывает ваше приложение с требованием / требованием именно этих экземпляров и делает его очень трудным для модульного тестирования.

Вместо этого вы должны использовать Unity в своей конечной точке (контроллер в MVC или код на страницах ASPX):

IUnityContainer ioc = new UnityContainer();
IPostService postService = ioc.Resolve<IPostService>();
IList<Post> posts = postService.GetPosts();

Обратите внимание, что в этом примере не используются бетоны (кроме UnityContainer и Post, очевидно)! Нет конкретных услуг и нет хранилища. Это слабосвязанное во всей красе.

Вот настоящий кикер ...

Unity (или любая инфраструктура контейнера IoC!) Будет проверять IPostService на наличие любых зависимостей. Он увидит, что он хочет (зависит) от экземпляра IPostRepository. Итак, Unity перейдет в свою карту объектов и найдет первый объект, который реализует IPostRepository, который был зарегистрирован в контейнере, и вернет его (то есть экземпляр SqlPostRepository). Это реальная сила структур IoC - возможность автоматически проверять сервисы и связывать любые зависимости.

Мне нужно закончить запись в своем блоге о сравнении UNITY против Castle против StructureMap. На самом деле я предпочитаю Castle Windsor из-за параметров его файла конфигурации и точек расширения лично.

4 голосов
/ 11 ноября 2009

Блок приложения Unity используется для внедрения зависимости . Я думаю, что лучшее простое определение для DI от этот вопрос

Когда вы идете и достаете вещи из холодильника для себя, у вас могут возникнуть проблемы. Вы можете оставить дверь открытой, вы можете получить что-то, что мама или папа не хотят, чтобы вы имели. Возможно, вы даже ищете что-то, чего у нас нет или срок действия которого истек.

То, что вы должны делать, - это заявить о необходимости: «Мне нужно что-нибудь выпить с обедом», и тогда мы позаботимся о том, чтобы у вас было что-нибудь, когда вы сядете поесть.

Так, например,

IUnityContainer container = new UnityContainer();
ILunch lunch = container.Resolve<ILunch>();
Console.WriteLine(lunch.Drink); 

Это выводит "Лимонад", потому что мы определили Drink как Зависимость.

public class ILunch {
    [Dependency]
    public IDrink Drink { get; set; }
} 

Что касается практичности, Dependency Injection действительно замечательно, когда у вас есть зависимости от других объектов, и вы не хотите, чтобы разработчик устанавливал их вручную. Это так просто. Это также отлично подходит для насмешек. Наиболее часто используемый пример, который я могу использовать, - это насмешка над слоем данных. Иногда база данных не готова, поэтому вместо остановки разработки у меня есть фальшивый слой, который возвращает фальшивые данные. Доступ к объекту данных осуществляется через DI, и его можно настроить так, чтобы он возвращал объекты, которые обращаются к поддельному слою или реальному слою. В этом примере я почти использую DI-контейнер в качестве настраиваемого фабричного класса. Более подробно о Unity MSDN имеет несколько замечательных ресурсов http://msdn.microsoft.com/en-us/library/cc468366.aspx.

Другие хорошие DI-фреймворки включают Spring.NET и Ninject

...