Использование Autofac для DI в службе WCF, размещенной в приложении ASP.NET - PullRequest
14 голосов
/ 28 июля 2010

У меня проблемы с добавлением зависимостей сервисов в мой сервис WCF с использованием Autofac 1.4.5.Я прочитал и следил за страницей Autofac wiki на WcfIntegration , но моя отладка показывает, что моя служба WCF создается методом System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance(), а не AutofacWebServiceHostFactory.Что я делаю не так?

Я настроил свой файл ajax.svc так, чтобы он выглядел так, как показано в примере для использования с WebHttpBinding:

<%@ ServiceHost Language="C#" Debug="true"
    Service="Generic.Frontend.Web.Ajax, Generic.Frontend.Web"
    Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory,
             Autofac.Integration.Wcf" %>

Мой класс обслуживания WCFAjax определяется следующим образом:

namespace Generic.Frontend.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Ajax
    {
        public MapWebService MapWebService { get; set;}

        public Ajax() {
            // this constructor is being called
        }

        public Ajax(MapWebService mapWebService)
        {
            // this constructor should be called
            MapWebService = mapWebService;
        }

        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract(Name = "mapchange")]
        public MapChangeResult ProcessMapChange(string args)
        {
            // use the injected service here
            var result = MapWebService.ProcessMapChange(args);
            return result;
        }
    }
}

Теперь я использовал разводку в Global.asax.cs, как показано в упомянутой выше вики:

var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacModuleWebservice());
var container = builder.Build();
AutofacServiceHostFactory.Container = container;

с

class AutofacModuleWebservice : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register<Ajax>();
        builder.Register<MapWebService>().ContainerScoped();
    }
}

В моем файле web.config у меня есть

<services>
    <service name="Generic.Frontend.Web.Ajax">
        <endpoint address="http://mysite.com/ajax.svc/" binding="webHttpBinding"
                  contract="Generic.Frontend.Web.Ajax" />
    </service>
</services>

.

Служба уже работает нормально, но я не могу получить биты Autofac (читай: создание / внедрение) работать.Есть идеи?

Редактировать: Удаление конструктора по умолчанию, к сожалению, приводит к следующему исключению:

System.InvalidOperationException:
The service type provided could not be loaded as a service because it does not
have a default (parameter-less) constructor. To fix the problem, add a default
constructor to the type, or pass an instance of the type to the host.

Приветствия, Оливер

Ответы [ 5 ]

1 голос
/ 16 августа 2010

Ваш сервис настроен с InstanceContextMode.Single? Если это так, то wcf создаст ваш сервис, используя конструктор по умолчанию. Чтобы обойти это, измените свой контекстный режим экземпляра и позвольте autofac управлять временем жизни вашего сервиса.

0 голосов
/ 04 октября 2013

Следуя инструкциям, все решено для меня:

code.google.com / p / autofac / wiki /… Я просто делаю: builder.RegisterType ();

и я следовал их указаниям по изменению файла .svc.

Когда вы смотрите на ваш файл .svc, вы не получаете никаких намеков на то, что что-то не так, кстати?

Вы размещаете его через iis и не используете WAS, я не вижу ваш код для переопределения global.asax.cs

Добавьте глобальный файл в ваше решение и там вы реализуете:

  protected void Application_Start(object sender, EventArgs e)
        {
            // build and set container in application start
            IContainer container = AutofacContainerBuilder.BuildContainer();
            AutofacHostFactory.Container = container;


        }

AutofacContainerBuilder - мой контейнерный конструктор.

0 голосов
/ 22 сентября 2011

У меня была такая же проблема, и я наткнулся на этот вопрос во время поиска ответа.

В моем случае использование внедрения свойств сработало, и у кода в вопросе уже есть свойство, которое можно использовать:

namespace Generic.Frontend.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Ajax
    {
        // inject the dependency here
        public MapWebService MapWebService { get; set;}

        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract(Name = "mapchange")]
        public MapChangeResult ProcessMapChange(string args)
        {
            // use the injected service here
            var result = MapWebService.ProcessMapChange(args);
            return result;
        }
    }
}

и зарегистрируйтесь, чтобы использовать внедрение свойства (пример кода из вики и синтаксиса изменился, поскольку теперь он использует версию 2.5.2.830):

builder.RegisterType<Ajax>().PropertiesAutowired();
0 голосов
/ 15 декабря 2010

Я только что получил то же исключение System.InvalidOperationException и решил его, изменив ServiceBehavior InstanceContextMode реализации с InstanceContextMode.PerCall на InstanceContextMode.PerSession, возможно, ваша область жизни AutoFac не синхронизирована с вашей реализацией веб-службы?

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

0 голосов
/ 29 июля 2010

Попробуйте удалить конструктор Ajax по умолчанию и измените его в соответствии с этим.Если он запускается с mapWebService == null, это указывает на проблему с разрешением.

    public Ajax(MapWebService mapWebService = null)
    {
        // this constructor should be called
        MapWebService = mapWebService;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...