ASP.NET MVC Dependency Injection Unity с сервисами WCF - рабочий пример решения - PullRequest
4 голосов
/ 01 сентября 2011

Я ищу рабочий пример веб-приложения ASP.NET MVC, которое использует Unity и вызывает службу WCF. Я посмотрел много объяснений о том, как добавить внедрение зависимостей в сервисы WCF, но, честно говоря, я немного над головой здесь. Не помогает и то, что я новичок в услугах WCF.

В настоящее время я использую Unity с внедрением Contructor для наших приложений ASP.NET MVC, но пока мы не используем какие-либо веб-службы WCF. План состоит в том, чтобы начать использовать веб-сервисы, и я очень озадачен тем, как интегрировать с ними Unity.

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

Ответы [ 3 ]

12 голосов
/ 01 сентября 2011

Я постараюсь дать вам некоторые рекомендации.

Предположим, что у вас есть существующая служба WCF для продуктов, которая определена следующим образом (нас не волнует реализация, на данный момент это не важно, вы можете реализовать ее по своему желанию, в отличие от жестко заданных значений, проходя через база данных SQL и ORM для использования другой службы в облаке):

[DataContract]
public class Product
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Name { get; set; }
}

[ServiceContract]
public interface IProductsService
{
    [OperationContract]
    Product Get(int id);
}

Теперь в вашем приложении ASP.NET MVC первый шаг - добавить ссылку на службу, указав на WSDL. Это сгенерирует прокси клиентские классы.

Затем вы можете добавить пакет Unity.Mvc3 NuGet в ваше приложение MVC

Тогда в вашем Application_Start вы можете сконфигурировать контейнер (очевидно, эта конфигурация может быть выведена в отдельный метод, чтобы не загромождать ваш Global.asax им):

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    var container = new UnityContainer();
    container
        .RegisterType<IProductsService, ProductsServiceClient>()
        .Configure<InjectedMembers>()
        .ConfigureInjectionFor<ProductsServiceClient>(new InjectionConstructor("*"));
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

IProductsService и ProducsServiceClient, используемые в этой конфигурации, являются прокси-классами, генерируемыми при импорте определения веб-службы.

Отныне вещи становятся тривиальными:

public class HomeController : Controller
{
    private readonly IProductsService _productsService;
    public HomeController(IProductsService productsService)
    {
        _productsService = productsService;
    }

    public ActionResult Index()
    {
        var product = _productsService.Get(1);
        return View(product);
    }
}

и некоторые соответствующие индексные представления:

@model Product
<div>
    @Html.DisplayFor(x => x.Name)
</div>

Как видно из этого примера, благодаря абстракции IProductsService, HomeController полностью отделен от любых конкретных реализаций службы. В Today в вашем Global.asax вы решили использовать WCF (ProductsServiceClient), но завтра вы можете решить использовать совсем другую реализацию. С помощью одного изменения конфигурации вашего DI-контейнера вы можете переключить реализацию. Благодаря этой слабой связи, ваши контроллеры могут быть полностью проверены модулем изолированно.

Здесь важно понимать, что ваш бизнес - это класс Product и интерфейс IProductsService. Это то, что отражает ваш домен. Это М в MVC. Реализации могут измениться, но это должно остаться без изменений, в противном случае вы ошибочно определили свои бизнес-требования, которые могут иметь катастрофические последствия в долгосрочной перспективе.

Примечание: одна вещь, которую я не рассмотрел в этом примере и которая очень важна, - это использование моделей представлений. В правильно спроектированном приложении ASP.NET MVC вы никогда не должны передавать доменные модели своим представлениям (в этом примере класс Product). Вы должны использовать просмотр моделей. Модели представлений - это классы, специально разработанные для требований данного представления. Таким образом, в реальном приложении ASP.NET MVC у вас будет класс ProductViewModel, которому будет сопоставлена ​​модель домена Product в действии контроллера, и именно эта ProductViewModel будет передана в представление. Эти модели представлений должны быть определены в проекте MVC, так как, в отличие от ваших моделей предметной области, они не могут быть использованы повторно и отражают только конкретные требования одного представления. Чтобы упростить сопоставление между моделями доменов и моделями представления, вы можете взглянуть на AutoMapper .

4 голосов
/ 01 сентября 2011

Похоже, вы уже вводите свои контроллеры MVC с помощью Unity, и все, что вам нужно сделать, - это начать внедрять службы WCF, которые вы также размещаете.Чтобы внедрить службы WCF, вам нужно использовать IInstanceProvider.

Полное рабочее решение здесь:

http://orand.blogspot.com/2006/10/wcf-service-dependency-injection.html

Вам нужно 4 очень очень простых класса:1009 *

MyServiceHostFactory 
MyServiceHost 
DependencyInjectionServiceBehavior
DependencyInjectionInstanceProvider 

определите их, укажите ваш новый ServiceHostFactory:

<%@ ServiceHost
Service="NamespaceC.ServiceLayer, AssemblyC"
Factory="NamespaceD.MyServiceHostFactory, AssemblyD"
%>

и все готово.

0 голосов
/ 02 февраля 2015

Я знаю, что в игре немного поздно, но я написал пакет Nuget, чтобы упростить процесс использования WCF в приложении MVC / WebApi, и он использует Unity.

Ознакомьтесь с Unity.Mvc.Wcf на Codeplex или GitHub для подробностей.

...