为了回答这个问题,我添加了新的 Modularizing services 和 Physical project structure wiki 页面,以突出构建和模块化 ServiceStack 服务的不同方式,我将重复听到这些方式以提高可发现性:
正如您所发现的,ServiceStack 对每个应用程序域都有一个单个应用程序主机。正如您可以从名称中推断的那样,Host 项目的作用是作为绑定所有服务具体依赖项、插件、过滤器和服务所需的所有其他内容的管道。在您的 AppHost.Configure() 方法中初始化所有内容后,您的服务配置应该是不可变的。 Physical project structure wiki page 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) {}
}
您还可以通过覆盖 CreateServiceManager 来提供自己的策略来发现和解析 ServiceStack 应自动连接的服务类型,例如:
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())));
}
}
在插件中封装服务
一种模块化服务的方法是将它们封装在Plugins 中,这允许您手动注册服务、自定义路由、过滤器、内容类型、允许自定义以及您的模块需要的任何其他内容。
为了说明这一点,我们将展示一个基本的Auth Feature 示例的样子:
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" });
请参阅此earlier answer,了解对项目进行物理布局的推荐方式。