Shared API
The Shared API allows plugins to expose interfaces that other plugins can consume, enabling inter-plugin communication and functionality sharing.
Overview
The Shared API system consists of two main methods in your plugin:
ConfigureSharedInterface: Register interfaces that your plugin provides to othersUseSharedInterface: Consume interfaces that other plugins have registered
Providing Shared Interfaces
To make your plugin's functionality available to other plugins, override the ConfigureSharedInterface method:
public override void ConfigureSharedInterface(IInterfaceManager interfaceManager) {
// Register your shared interfaces here
}Adding a Shared Interface
Use AddSharedInterface to register an interface implementation:
interfaceManager.AddSharedInterface<IMyService, MyServiceImpl>("MyPlugin.MyService", new MyServiceImpl());Parameters:
TInterface: The interface type (must be defined in a contracts DLL)TImpl: The implementation classkey: A unique string identifier for this interfaceimplInstance: The instance of your implementation
The interface must be defined in a separate contracts DLL that can be referenced by both the provider and consumer plugins.
Consuming Shared Interfaces
To use interfaces provided by other plugins, override the UseSharedInterface method:
public override void UseSharedInterface(IInterfaceManager interfaceManager) {
// Get shared interfaces from other plugins here
}Checking if an Interface Exists
Before consuming an interface, you can check if it's available:
if (interfaceManager.HasSharedInterface("MyPlugin.MyService")) {
// Interface is available
}Getting a Shared Interface
Use GetSharedInterface to retrieve an interface implementation:
var myService = interfaceManager.GetSharedInterface<IMyService>("MyPlugin.MyService");Complete Example
Here's a complete example showing how two plugins can communicate via the Shared API.
1. Create a Contracts Project
First, create a shared contracts DLL that both plugins will reference:
// File: MyPlugin.Contracts/IEconomyService.cs
namespace MyPlugin.Contracts;
public interface IEconomyService {
int GetPlayerBalance(int playerId);
void AddPlayerBalance(int playerId, int amount);
bool RemovePlayerBalance(int playerId, int amount);
}The contract DLL must be put inside resources/exports folder of the plugin.
2. Provider Plugin (Economy Plugin)
The plugin that provides the functionality:
// File: EconomyPlugin/EconomyService.cs
using MyPlugin.Contracts;
namespace EconomyPlugin;
public class EconomyService : IEconomyService {
private Dictionary<int, int> _balances = new();
public int GetPlayerBalance(int playerId) {
return _balances.TryGetValue(playerId, out var balance) ? balance : 0;
}
public void AddPlayerBalance(int playerId, int amount) {
_balances[playerId] = GetPlayerBalance(playerId) + amount;
}
public bool RemovePlayerBalance(int playerId, int amount) {
var currentBalance = GetPlayerBalance(playerId);
if (currentBalance < amount) return false;
_balances[playerId] = currentBalance - amount;
return true;
}
}
// File: EconomyPlugin/Plugin.cs
public class Plugin : SwiftlyPlugin {
public override void ConfigureSharedInterface(IInterfaceManager interfaceManager) {
var economyService = new EconomyService();
interfaceManager.AddSharedInterface<IEconomyService, EconomyService>(
"Economy.Service",
economyService
);
}
}3. Consumer Plugin (Shop Plugin)
The plugin that consumes the economy functionality:
// File: ShopPlugin/Plugin.cs
using MyPlugin.Contracts;
public class Plugin : SwiftlyPlugin {
private IEconomyService? _economyService;
public override void UseSharedInterface(IInterfaceManager interfaceManager) {
if (interfaceManager.HasSharedInterface("Economy.Service")) {
_economyService = interfaceManager.GetSharedInterface<IEconomyService>("Economy.Service");
Console.WriteLine("Successfully connected to Economy service!");
} else {
Console.WriteLine("Warning: Economy plugin not found!");
}
}
public void BuyItem(int playerId, int itemPrice) {
if (_economyService == null) {
Console.WriteLine("Economy service not available!");
return;
}
var balance = _economyService.GetPlayerBalance(playerId);
if (balance < itemPrice) {
Console.WriteLine("Insufficient funds!");
return;
}
if (_economyService.RemovePlayerBalance(playerId, itemPrice)) {
Console.WriteLine("Item purchased successfully!");
}
}
}Best Practices
Clear Events
If your API contains events that can be registered by other plugins, make sure to set them to null or create a new API object to provide to the interfaceManager each time ConfigureSharedInterface is called. Otherwise, events may be registered multiple times.
Ensure Your Interface Inherits IDisposable
In most cases, we recommend making your interface disposable and adding disposed checks.
When a shared interface is unloaded, the framework will automatically call the dispose method of each shared interface (if it inherits IDisposable),
which ensures that deprecated API objects are not used incorrectly.
Use Descriptive Keys
Use a consistent naming convention for interface keys:
// Good: Plugin name + service description
"EconomyPlugin.CurrencyService"
"PermissionsPlugin.AuthService"
// Avoid: Generic or ambiguous names
"Service"
"API"Handle Missing Dependencies
Always check if an interface exists before using it:
public override void UseSharedInterface(IInterfaceManager interfaceManager) {
if (!interfaceManager.HasSharedInterface("Economy.Service")) {
Console.WriteLine("Warning: Economy plugin is not loaded!");
// Provide fallback behavior or disable features
return;
}
_economyService = interfaceManager.GetSharedInterface<IEconomyService>("Economy.Service");
}Version Your Interfaces
Consider versioning your interface keys if you plan to make breaking changes:
interfaceManager.AddSharedInterface<IEconomyServiceV2, EconomyServiceV2>(
"Economy.Service.v2",
new EconomyServiceV2()
);Store Shared Interfaces in Fields
Store retrieved interfaces in class fields for easy access throughout your plugin:
public class Plugin : SwiftlyPlugin {
private IEconomyService? _economy;
private IPermissionsService? _permissions;
public override void UseSharedInterface(IInterfaceManager interfaceManager) {
_economy = interfaceManager.GetSharedInterface<IEconomyService>("Economy.Service");
_permissions = interfaceManager.GetSharedInterface<IPermissionsService>("Permissions.Service");
}
}Reference
See IInterfaceManager for more details.