7

我一直在评估 ServiceStack,到目前为止,我已经卖得差不多了——但我有一个我认为会破坏交易的要求。

我基本上需要多个 AppHost 派生实例。第一个很好地旋转起来,但其余的都失败了,因为“AppHostBase.Instance 已经设置”。

这是否意味着如果我想要多个主机(在不同的 Uris 上)位于不同的可执行文件中?如果是这样,这是相当令人失望的,因为这个库在其他方面都是完美的,除了这个限制。

如果我错了,谁能指出我的解决方案?

请允许我稍微详细说明一下。我们计划在整个网络中提供许多服务。我的意图是将它们设计为单独的服务,然后在托管类中“托管”。托管类本身是用于管理目的的服务,并且具有启动和停止服务的能力。它们在网络上是“可发现的”。我们可以在不同时间或随意启动和关闭不同机器上的服务。

我的计划是为这些事情中的每一个使用服务堆栈,并能够在任何机器和任何“主机”上以临时方式创建和销毁服务。我唯一遇到的问题是 AppHost 只被初始化一次。

显然我做错了什么,所以任何关于如何在同一个可执行文件中托管多个服务的信息都会很棒:)

4

1 回答 1

12

为了回答这个问题,我添加了新的模块化服务物理项目结构wiki 页面,以突出构建和模块化 ServiceStack 服务的不同方式,我将重复听到这些方式的可发现性:

正如您所发现的,ServiceStack为每个应用程序域提供了一个应用程序主机。正如您可以从名称中推断的那样,Host项目的作用是成为绑定所有服务具体依赖项、插件、过滤器和服务所需的所有其他内容的管道。AppHost.Configure()在您的方法中初始化所有内容后,您的服务配置应该是不可变的。物理项目结构 wiki 页面wiki 显示了典型解决方案的推荐物理项目结构。

在多个组件中模块化服务

虽然您只能拥有 1 个 AppHost,但可以通过在 AppHostBase 构造函数中提供程序集来将服务分布在多个程序集中,例如:

public class AppHost : AppHostBase
{
    //Tell Service Stack the name of your application and which assemblies to find your web services
    public AppHost() : base("Hello ServiceStack!", 
       typeof(ServicesFromDll1).Assembly, ServicesFromDll2).Assembly /*, etc */) { }

    public override void Configure(Container container) {}
}

您还可以提供自己的策略来发现和解决 ServiceStack 应该通过覆盖自动连接的服务类型CreateServiceManager,例如:

public class AppHost : AppHostBase
{
    public AppHost() : base("Hello ServiceStack!", typeof(ServicesFromDll1).Assembly) { }
    public override void Configure(Container container) {}

    //Provide Alternative way to inject IOC Container + Service Resolver strategy
    protected virtual ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices)
    {       
        return new ServiceManager(new Container(),
            new ServiceController(() => assembliesWithServices.ToList().SelectMany(x => x.GetTypes())));
    }
}

在插件中封装服务

模块化服务的一种方法是将它们封装在插件中,这允许您手动注册服务、自定义路由、过滤器、内容类型、允许自定义以及您的模块需要的任何其他内容。

为了说明这一点,我们将展示一个基本身份验证功能示例的样子:

public class BasicAuthFeature : IPlugin 
{
    public string HtmlRedirect { get; set; }   //User-defined configuration

    public void Register(IAppHost appHost)
    {
        //Register Services exposed by this module
        appHost.RegisterService<AuthService>("/auth", "/auth/{provider}");
        appHost.RegisterService<AssignRolesService>("/assignroles");
        appHost.RegisterService<UnAssignRolesService>("/unassignroles");

        //Load dependent plugins
        appHost.LoadPlugin(new SessionFeature());
    }
}

将所有内容都封装在插件中,您的用户可以通过以下方式轻松地在您的 AppHost 中启用它们:

Plugins.Add(new BasicAuthFeature { HtmlRedirect = "~/login" });

物理项目结构

有关物理布局项目的推荐方式,请参阅此较早的答案。

于 2013-04-06T18:04:46.510 回答