我目前正在使用WebServiceHost
在Windows服务(而非IIS)中运行一些WCF REST服务。我为每个服务定义了单独的接口和类,但是在理解如何将WebServiceHost
,ServiceEndpoint
和ServiceContracts
一起使用以创建自托管解决方案时遇到了一些问题。
我目前设置的方式是,我为每个实现服务的类创建一个新的WebServiceHost
,并使用该类的名称作为URI的一部分,然后在接口中定义URI的其余部分。
[ServiceContract]
public interface IEventsService
{
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebGet(UriTemplate = "EventType", ResponseFormat=WebMessageFormat.Json)]
List<EventType> GetEventTypes();
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebGet(UriTemplate = "Event")]
System.IO.Stream GetEventsAsStream();
}
public class EventsService: IEventsService
{
public List<EventType> GetEventTypes() { //code in here }
public System.IO.Stream GetEventsAsStream() { // code in here }
}
创建服务的代码如下所示:
Type t = typeof(EventService);
Type interface = typeof(IEventService);
Uri newUri = new Uri(baseUri, "Events");
WebServicesHost host = new WebServiceHost(t, newUri);
Binding binding = New WebHttpBinding();
ServiceEndpoint ep = host.AddServiceEndpoint(interface, binding, newUri);
这很好用,并且每个服务的服务端点都在适当的URL上创建。
http://XXX.YYY.ZZZ:portnum/Events/EventType
http://XXX.YYY.ZZZ:portnum/Events/Event
然后,我重复另一个服务接口和服务类。我想在网址中删除
Events
,但是如果我这样做并使用相同的基本URL创建多个WebServiceHosts
,则会收到错误消息:The ChannelDispatcher at 'http://localhost:8085/' with contract(s) '"IOtherService"' is unable to open its IChannelListener
具有以下内部异常:
"A registration already exists for URI 'http://localhost:8085/'."
我试图了解
WebServiceHost
,ServiceEndpoint
和ServiceContract
如何共同创建ChannelListener。每个实现服务的类是否都需要一个单独的
WebServiceHost
?我看不到用单个WebServiceHost
注册多种类型的方法其次,我将接口传递给AddServceEndpoint方法,并假定该方法检查所有OperationContract成员的对象并将其添加,问题是WebServiceHost如何知道哪个类应映射到哪个接口。
我想举一个创建WCF自托管服务的示例,该服务运行多个服务,同时使接口和实现类保持分离。
最佳答案
在我看来,您遇到的问题是您试图在同一服务URI上注册多个服务。正如您已经注意到的那样,这将不起作用,每个服务必须具有唯一的端点。
唯一依据
知识产权
域
端口号
完整网址
例子
http://someserver/foo -> IFoo Service
http://someserver/bar -> IBar Service
http://somedomain -> IFoo Service
http://someotherdomain -> IBar Service
http://somedomain:1 -> IFoo Service
http://somedomain:2 -> IBar Service
你明白了。
因此,要直接解决您的问题,如果您希望将多个服务放在您网站的根URL中,则必须将它们放在不同的端口上。因此,您可以将代码修改为类似
public class PortNumberAttribute : Attribute
{
public int PortNumber { get; set; }
public PortNumberAttribute(int port)
{
PortNumber = port;
}
}
[PortNumber(8085)]
public interface IEventsService
{
//service methods etc
}
string baseUri = "http://foo.com:{0}";
Type iface = typeof(IEventsService);
PortNumberAttribute pNumber = (PortNumberAttribute)iface.GetCustomAttribute(typeof(PortNumberAttribute));
Uri newUri = new Uri(string.Format(baseUri, pNumber.PortNumber));
//create host and all that