是否可以使用没有config或svc文件的castle windsor fluent配置来配置WCF服务?

时间:2012-01-11 15:34:54

标签: c# asp.net wcf castle-windsor

我在IIS上托管了一个ASP .Net MVC 3.0 Web应用程序,我正在使用Castle Windsor 3.0版。

我想要做的是使用webHttpBinding注册WCF服务,而不使用web.config中的任何条目或使用.svc文件。这可能吗?

我在IWindsorInstaller实现中试过这个:

container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero);

container.Register(
    Component
        .For<IMyService>()
        .ImplementedBy<MyService>()
        .AsWcfService(new DefaultServiceModel()
                          .AddBaseAddresses("http://localhost/WebApp/Services")
                          .AddEndpoints(WcfEndpoint
                                    .BoundTo(new WebHttpBinding())
                                    .At("MyService.serv"))
                          .Hosted()
                          .PublishMetadata()));

我忽略了在全局asax的RegisterRoutes方法中完成serv的任何事情:

routes.IgnoreRoute("{resource}.serv/{*pathInfo}");

如果我将浏览器指向http://localhost/WebApp/Services/MyService.serv,我会收到404。

我做错了什么,或者我想做一些愚蠢的事情(或者不可能或两者兼而有之!)?

1 个答案:

答案 0 :(得分:7)

感谢Ladislav建议使用ServiceRoute我已经找到了如何做到这一点,但我不确定它是否理想,这就是我所做的(如果Google员工发现它并且可以改进它等):

在ComponentRegistration上创建了一个扩展方法,如下所示:

public static ComponentRegistration<T> AddServiceRoute<T>(
    this ComponentRegistration<T> registration, 
    string routePrefix, 
    ServiceHostFactoryBase serviceHostFactory, 
    string routeName) where T : class
{
    var route = new ServiceRoute("Services/" + routePrefix + ".svc",
                                 serviceHostFactory,
                                 registration
                                     .Implementation
                                     .GetInterfaces()
                                     .Single());
    RouteTable.Routes.Add(routeName, route);           
    return registration;
}   

它的作用是添加一个服务路由,将服务放在Services文件夹下并固定在.svc扩展名上(我可能会删除它)。注意,我假设该服务只实现了一个接口,但在我的情况下,这很好,我认为无论如何都是好的做法。

我不确定这是获得此扩展方法的最佳位置,或者即使实际上根本需要扩展方法 - 也许我应该使用服务主机构建器或其他东西,我不知道!

然后在MapRoute调用中,我确保根据问题MVC2 Routing with WCF ServiceRoute: Html.ActionLink rendering incorrect links!将其添加到constraints参数

new { controller = @"^(?!Services).*" }

这只会使启动服务的任何内容无法与控制器匹配。我不太喜欢这个,因为我必须将它添加到我的所有路由中 - 我宁愿全局使Services文件夹落入服务解析器或其他东西(我对MVC看起来不太了解!)。

最后在我的windsor安装程序中,我注册了这样的服务:

container.AddFacility<WcfFacility>(
    f =>
        {
            f.Services.AspNetCompatibility = 
                AspNetCompatibilityRequirementsMode.Allowed;
            f.CloseTimeout = TimeSpan.Zero;
        });

container.Register(
    Component
        .For<IMyService>()
        .ImplementedBy<MyService>()
        .AsWcfService(new DefaultServiceModel()
                         .AddEndpoints(WcfEndpoint.BoundTo(new WebHttpBinding()))
                         .Hosted()
                         .PublishMetadata())
        .AddServiceRoute("MyService", new DefaultServiceHostFactory(), null));

之后,我可以浏览到该服务,它被拾取并构建得很好!

正如我所提到的,它可能不是最好的方法,但它确实有效。