3

我还没有找到其他人遇到这个问题,所以我假设发生这种情况是我自己的错。当谈到 WCF 和 Castle Windsor IoC 容器时,我非常绿色,所以这可能是发生这种情况的第一个原因。无论如何,我已经为此苦苦挣扎了几天,还没有找到原因。

首先,我使用 Castle Windsor 注册了我的服务。

var baseUri = new Uri("http://localhost:49246");

_container = new WindsorContainer();

var returnFaults = new ServiceDebugBehavior
{
    IncludeExceptionDetailInFaults = true,
    HttpHelpPageEnabled = true
};
var metadata = new ServiceMetadataBehavior { HttpGetEnabled = true };

_container.Register(
    Component.For<IServiceBehavior>().Instance(returnFaults),
    Component.For<IServiceBehavior>().Instance(metadata));

var baseUri = new Uri("http://localhost:49246");

_container = new WindsorContainer();

var returnFaults = new ServiceDebugBehavior
{
    IncludeExceptionDetailInFaults = true,
    HttpHelpPageEnabled = true
};
var metadata = new ServiceMetadataBehavior { HttpGetEnabled = true };

_container.Register(
    Component.For<IServiceBehavior>().Instance(returnFaults),
    Component.For<IServiceBehavior>().Instance(metadata));

_container
    .Register(
        Component
            .For<IAccountDataAccessor>()
                .ImplementedBy<AccountDataAccessor>(),
        Component
            .For<IInstitutionDataAccessor>()
                .ImplementedBy<InstitutionDataAccessor>(),
        Component
            .For<IRelationshipDataAccessor>()
                .ImplementedBy<RelationshipDataAccessor>(),
        Component
            .For<ITransactionDataAccessor>()
                .ImplementedBy<TransactionDataAccessor>()

    );

_container.AddFacility<WcfFacility>(f => { f.CloseTimeout = TimeSpan.Zero; });
_container.Register(
    Component
        .For<IAccountDataService>()
        .ImplementedBy<AccountDataService>()
        .Named("AccountDataService")
        .LifeStyle.Is(Castle.Core.LifestyleType.Singleton)
        .AsWcfService(new DefaultServiceModel()
            .AddBaseAddresses(baseUri)
            .AddEndpoints(WcfEndpoint
                .ForContract(typeof(IAccountDataService))
                .BoundTo(new WSHttpBinding()))),
    Component
        .For<IInstitutionDataService>()
        .ImplementedBy<InstitutionDataService>()
        .Named("InstitutionDataService")
        .LifeStyle.Is(Castle.Core.LifestyleType.Singleton)
        .AsWcfService(new DefaultServiceModel()
            .AddBaseAddresses(baseUri)    
            .AddEndpoints(WcfEndpoint
                .ForContract(typeof(IInstitutionDataService))
                .BoundTo(new WSHttpBinding()))),
    Component
        .For<IRelationshipDataService>()
        .ImplementedBy<RelationshipDataService>()
        .Named("RelationshipDataService")
        .LifeStyle.Is(Castle.Core.LifestyleType.Singleton)
        .AsWcfService(new DefaultServiceModel()
            .AddBaseAddresses(baseUri)
            .AddEndpoints(WcfEndpoint
                .ForContract(typeof(IRelationshipDataService))
                .BoundTo(new WSHttpBinding()))),
    Component
        .For<ITransactionDataService>()
        .ImplementedBy<TransactionDataService>()
        .Named("TransactionDataService")
        .LifeStyle.Is(Castle.Core.LifestyleType.Singleton)
        .AsWcfService(new DefaultServiceModel()
            .AddBaseAddresses(baseUri)    
            .AddEndpoints(WcfEndpoint
                .ForContract(typeof(ITransactionDataService))
                .BoundTo(new WSHttpBinding()))));

现在,当我尝试获取 AccountDataService 的服务参考时,它工作正常,没有错误。但是,当我尝试添加对机构数据服务的服务引用时,它会抛出一个异常:

    Could not find a component with name InstitutionDataService, did you forget to register it?

这非常令人沮丧,我似乎无法在 Castle Windsor 文档中找到一个直接的答案(或缺少答案)。我试图实施这个 SO 问题中建议的解决方案:

所以问题

但这也没有用。似乎没有任何组件已注册。另外,如果有帮助,这是我的 svc 标记:

    <%@ ServiceHost Language="C#" Debug="true" Service="AccountDataService"
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>

所有服务都是一样的。

所以,我的问题是,为什么我的组件没有与 AccountDataService 一起注册?

4

2 回答 2

3

以下是我如何通过没有 app.config 文件的代码进行配置。

一个区别是我在 DefaultServiceModel 上使用 PublishMetadata 方法,而不是使用 IServiceBehavior 注册它。老实说,如果同一个接口被注册两次并且它不是装饰器模式,我不确定 Windsor 会如何表现(参见这篇关于 Windsor 和装饰器的帖子)。

另一个区别是我在 AddBaseAddress 方法中为每个服务指定了一个唯一地址。每个服务都需要一个唯一的地址,但您可以使用 WcfEndpoint 上的 At() 方法公开与每个服务的基地址相关的多个唯一终结点。(即,如果您想为同一服务公开 BasicHttpEndpoint 和 WSHttpEndpoint)

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace DISandbox
{
    public class Program
    {
        private static WindsorContainer _container;

        public static void Main(string[] args)
        {
            _container = new WindsorContainer();
            _container.AddFacility<WcfFacility>();

            ServiceDebugBehavior returnFaults = new ServiceDebugBehavior
            {
                IncludeExceptionDetailInFaults = true,
                HttpHelpPageEnabled = true,
            };

            _container.Register(
                Component.For<IServiceBehavior>().Instance(returnFaults));

            string baseAddress = "http://localhost:49246/";

            _container.Register(
                Component
                    .For<IAccountDataService>()
                    .ImplementedBy<AccountDataService>()
                    .AsWcfService(new DefaultServiceModel()
                        .PublishMetadata(mex => mex.EnableHttpGet())
                        .AddBaseAddresses(baseAddress + "AccountDataService")
                        .AddEndpoints(WcfEndpoint
                            .ForContract<IAccountDataService>()
                            .BoundTo(new WSHttpBinding()))),
                Component
                    .For<IInstitutionDataService>()
                    .ImplementedBy<InstitutionDataService>()
                    .AsWcfService(new DefaultServiceModel()
                        .PublishMetadata(mex => mex.EnableHttpGet())
                        .AddBaseAddresses(baseAddress + "InstitutionDataService")
                        .AddEndpoints(WcfEndpoint
                            .ForContract<IInstitutionDataService>()
                            .BoundTo(new WSHttpBinding()))));

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
    }

    [ServiceContract]
    public interface IAccountDataService
    {
        [OperationContract]
        void DoStuff();
    }

    public class AccountDataService : IAccountDataService
    {
        public void DoStuff() { }
    }

    [ServiceContract]
    public interface IInstitutionDataService
    {
        [OperationContract]
        void DoStuff();
    }

    public class InstitutionDataService : IInstitutionDataService
    {
        public void DoStuff() { }
    }
}
于 2012-11-08T20:12:35.613 回答
2

这是我使用 app.config 文件自行托管的方法。我这样做是因为这是我熟悉的。如果需要,我可以将其修改为通过代码而不是通过 app.config 文件进行配置...

using System;
using System.ServiceModel;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace DISandbox
{
    public class Program
    {
        private static WindsorContainer _container;

        public static void Main(string[] args)
        {
            _container = new WindsorContainer();
            _container.AddFacility<WcfFacility>();

            _container.Register(
                Component
                    .For<IAccountDataService>()
                    .ImplementedBy<AccountDataService>()
                    .AsWcfService(),
                Component
                    .For<IInstitutionDataService>()
                    .ImplementedBy<InstitutionDataService>()
                    .AsWcfService());

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
    }

    [ServiceContract]
    public interface IAccountDataService
    {
        [OperationContract]
        void DoStuff();
    }

    public class AccountDataService : IAccountDataService
    {
        public void DoStuff() { }
    }

    [ServiceContract]
    public interface IInstitutionDataService
    {
        [OperationContract]
        void DoStuff();
    }

    public class InstitutionDataService : IInstitutionDataService
    {
        public void DoStuff() { }
    }
}

还有配置文件...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyHttpServiceBehavior">
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="True" httpHelpPageEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service name="DISandbox.AccountDataService" behaviorConfiguration="MyHttpServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:49246/AccountDataService"/>
          </baseAddresses>
        </host>
        <endpoint binding="basicHttpBinding" contract="DISandbox.IAccountDataService" />
      </service>

      <service name="DISandbox.InstitutionDataService" behaviorConfiguration="MyHttpServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:49246/InstitutionDataService"/>
          </baseAddresses>
        </host>
        <endpoint binding="basicHttpBinding" contract="DISandbox.IInstitutionDataService" />
      </service>
    </services>
  </system.serviceModel>

</configuration>
于 2012-11-08T16:47:42.363 回答