• 中文
  • 注册
  • 技术交流 技术交流 关注:3 内容:13

    OpenMod插件的服务

  • 查看作者
  • 打赏作者
  • 当前位置: 未转变者中文社区 > 技术交流 > 正文
    • 技术交流
    • 搬运自OpenMod官网,经过翻译,可能有些不足,欢迎指正!原文链接

      服务和依赖注入

      OpenMod与其他基于.NET的现代框架一样,使用依赖注入模式。本指南旨在简化它,并解释它对使用OpenMod的插件开发人员意味着什么。

      插件、命令、事件监听器和服务可以自动获取对插件或OpenMod提供的任何其他服务的引用,只需将它们的接口添加到构造函数中。请参见下面的示例。

      依赖注入示例

      让我们看看这个活动:

      这就是你的插件通常的样子:

      public class MyPlugin(IServiceProvider serviceProvider) : base(serviceProvider)
      {
       
      }

      如果您想访问IStringLocalizer服务,您可以这样做:

      public class MyPlugin(IStringLocalizer stringLocalizer, IServiceProvider serviceProvider) : base(serviceProvider)
      {
         // 用stringLocalizer做些什么
      }

      假设您希望通过命令访问插件实例和配置。以下是您的方法:

      private readonly IConfiguration m_Configuration;
      private readonly MyPlugin m_MyPlugin;
       
      public EchoCommand(
          IServiceProvider serviceProvider, 
          MyPlugin myPlugin,
          IConfiguration configuration) : base(serviceProvider)
          m_MyPlugin = myPlugin;
          m_Configuration = configuration;
      }

      注册您自己的服务

      注册服务有两种方法:

      使用接口的[Service]属性和具体类的[PluginServiceImplementation]进行注册。

      通过实现IServiceConfiguratorIContainerConfigurator接口手动注册。当配置IoC容器时,实现这些接口的类将自动实例化,并可用于直接配置容器。

      您可以实现IDisposableIAsyncDisposable接口,以便在OpenMod或插件卸载时清理资源。

      以下是清理车辆的示例服务:

      [Service]
      public interface IVehicleClearingService
      {
          Task ClearVehiclesAsync();
      }
       
      [PluginServiceImplementation(Lifetime = ServiceLifetime.Transient)]
      public class VehicleClearingService : IVehicleClearingService, IAsyncDisposable
      {
          private readonly IStringLocalizer m_StringLocalizer;
          private readonly ILogger<VehicleClearingService> m_Logger;
          public VehicleClearingService(
              ILogger<VehicleClearingService> logger, 
              IPluginAccessor<VehicleClearerPlugin> pluginAccessor)
          {
              VehicleClearerPlugin plugin = pluginAccessor.Instance;
       
              // 服务位于全局OpenMod作用域中,该作用域不提供IStringLocalizer。
              // 因为IStringLocalizer不在这个范围内,所以我们必须使用plugins范围。
              m_StringLocalizer = plugin.Lifetime.Resolve<IStringLocalizer>();
              m_Logger = logger;
          }
          public async Task ClearVehiclesAsync() 
          {
              m_Logger.LogInformation(m_StringLocalizer["messages:clearing_vehicles"]); // 翻译是从plugins translation中读取的
              // 调用游戏API清除车辆...
          }
          // 在OpenMod重载或服务器关闭时调用服务dispose方法 
          public async ValueTask DisposeAsync()
          {
              await ClearVehiclesAsync(); // 确保车辆在重新装载或关闭时被清除
          }
      }

      现在,您可以通过在命令、事件侦听器、插件类或其他服务中注入IVehicleClearingService来访问此服务。

      服务期限

      您可能已经注意到,VehicleClearningService的生存期设置为Lifetime = ServiceLifetime.Transient

      以下生存期可用:

      Transient-每次解析时都会重新创建服务。此服务的每个解析和注入都将有一个唯一的实例。这是默认的生存期。

      Scoped-服务将在同一命令或事件中共享同一实例。

      Singleton-服务将只有一个实例的生存期与OpenMod IoC容器的生命周期相同(直到OpenMod重新加载或服务器关闭)。

      避免使用单例服务。如果您的服务具有暂时的或作用域的依赖关系,这可能会导致问题。

      服务范围

      服务可以有两个作用域:插件作用域和全局作用域。

      插件作用域服务仅在定义插件本身中使用,其他插件无法访问。它们也不能覆盖OpenMod本身或其他插件的全局范围服务。插件作用域服务是使用[PluginServiceImplementation]属性实现的。插件作用域服务是在加载插件时构造的,在关闭插件时释放。

      全局作用域服务用于所有插件和OpenMod本身。全局作用域服务是使用[ServiceImplementation]属性实现的。如果您想为每个人替换例如IStringLocalizer,您需要在全局范围内实现它。全局作用域服务在OpenMod重新加载或服务器关闭时被释放。全局作用域服务是在OpenMod加载并被释放和OpenMod关闭时构建的。

      在实现全局范围服务时避免依赖于插件。仅创建对其他全局范围服务的依赖关系。由于全局范围服务的生存期与插件不同,因此不能注入插件实例。一种解决方法是注入Lazy<IPluginAccessor<YourPlugin>>并稍后解析。请记住,即使您的插件无法加载或卸载,您的全局范围服务仍将保持活动状态。

      内置的OpenMod服务

      服务 说明
      IConfiguration 提供配置文件中的值
      ICommandContextBuilder 生成命令上下文
      ICommandExecutor 执行命令
      ICommandStore 提供命令注册
      ICommandPermissionBuilder 定义命令的权限
      ICommandParameterResolver 从字符串分析命令参数
      ICurrentCommandContextAccessor 访问当前命令上下文
      IDataStore 序列化和反序列化持久数据
      IDataStoreFactory 创建数据存储
      IEventBus 订阅事件并发出它们
      IJobSchgeduler 任务和管理作业
      ILogger<T> 为T类提供日志记录
      ILoggerFactory 创建者记录器
      IOpenModStringLocalizer 本地化来自OpenMod自己的翻译文件的消息
      IOpenModDataStoreAccessor 访问OpenMod自己的数据存储
      IOpenModHost OpenMod主机平台抽象
      IPermissionChecker 检查权限
      IPermissionRoleStore 存储权限角色
      IPermissionRegistry 注册和存储权限
      IPluginAccessor<TPlugin> 访问插件实例
      IPluginActivator 加载并激活插件
      IRuntime 创建并托管OpenMod运行时
      IStringLocalizer 本地化来自插件翻译文件的消息
      IUserDataSeeder 在第一次连接时种子用户数据
      IUserDataStore 存储和管理用户数据
      IUserManager 保姆用户

      请登录之后再进行评论

      登录
      极客之爱
      个人签名:收容失效服务器群组QQ群:1037114248
      关注2 粉丝1 喜欢2内容14
      上海
    • 做任务
    • 实时动态
    • 签到中心
      小黑屋
    • 到底部