簡體   English   中英

使用Autofac將DI轉換為ASP.NET應用程序中托管的WCF服務

[英]Using Autofac for DI into WCF service hosted in ASP.NET application

我在使用Autofac 1.4.5將服務依賴項注入WCF服務時遇到了麻煩。 我已經閱讀並關注了WcfIntegration上Autofac Wiki頁面,但調試顯示我的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" %>

我的WCF服務類Ajax的定義如下:

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的接線,如上面提到的Wiki所示:

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.

干杯,奧利弗

是否使用InstanceContextMode.Single設置服務? 如果是,則wcf將使用默認構造函數創建服務。 要解決此問題,請更改實例上下文模式,並讓autofac管理服務的生命周期。

遵循說明為我解決了問題:

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是我的容器生成器。

嘗試刪除默認的Ajax構造函數並將其修改為此。 如果使用mapWebService == null來運行, mapWebService == null表明存在解析問題。

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

我只是得到了相同的System.InvalidOperationException,並通過將實現的ServiceBehavior InstanceContextMode從InstanceContextMode.PerCall更改為InstanceContextMode.PerSession來解決了它,也許您的AutoFac生存期范圍與Web服務實現不同步嗎?

對於測試AutoFac服務的創建,我建議創建一個單元測試並直接解決它們,因為這將突出顯示所有問題並給出更有意義的異常消息。 對於具有請求生存期范圍的服務,請創建一個測試aspx頁面,然后再次直接解決它們。

我遇到了同樣的問題,在尋找答案時遇到了這個問題。

就我而言,使用屬性注入是可行的,問題中的代碼已經具有可以使用的屬性:

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;
        }
    }
}

並注冊以使用屬性注入(Wiki的示例代碼和語法已更改,因為現在使用的是2.5.2.830版本):

builder.RegisterType<Ajax>().PropertiesAutowired();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM