Changes

Jump to navigation Jump to search
move content from Modding:Modder Guide/APIs (only author is Pathoschild)
{{../../header}}

==Mod-provided APIs==
Mods can provide their own APIs to other mods, even without a dependency or assembly reference. This can be used to integrate mods, provide custom information, or provide new framework APIs beyond those offered by SMAPI itself.

===Providing an API===
To provide an API for other mods to use:
<ol>
<li>Add a normal class to your mod project with the methods and properties you want to expose.
<source lang="c#">
public class YourModApi
{
public string ExampleProperty { get; set; } = "Example value";

public bool GetThing(string example)
{
return true;
}
}
</source>
(You can use a [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors constructor] to initialise the API if desired.)</li>
<li>Override <tt>GetApi</tt> in your mod's entry class and return an instance of your API:
<source lang="c#">
public override object GetApi()
{
return new YourModApi();
}
</source></li>
</ol>

That's it! SMAPI will get one instance of your API and cache it.

Notes:
* <tt>GetApi</tt> is always called after <tt>Entry</tt>, so it's safe to pass in your mod's initialised fields.
* Be careful when changing your API! If you make a breaking change, other mods may need an update before they can access your API again.
* You can optionally add a public [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface interface] to your API. If a mod directly references your mod DLL, they'll be able to use your interface instead of creating their own.
* '''Known issue:''' SMAPI doesn't currently support non-public API classes.

===Using an API===
You can use a mod-provided API by mapping it to an [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface interface]:
<ol>
<li>Create an interface with only the properties and methods you want to access. (If you directly reference the mod DLL and it provides a public API interface, you can use that instead.)
<source lang="C#">
internal interface ISomeModApi
{
bool GetThing(string example);
}
</source></li>
<li>In your mod code (after <tt>Entry</tt>), you can get the API by specifying the interface you created in step 1, and the [[#Basic fields|mod's unique ID]]:
<source lang="c#">
ISomeModApi api = helper.ModRegistry.GetApi<ISomeModApi>("other-mod-ID");
if (api != null)
bool result = api.GetThing("boop");
</source></li>
</ol>

For a quick integration, you can also use reflection instead of creating an interface:
<source lang="c#">
object api = helper.ModRegistry.GetApi("other-mod-id");
if (api != null)
bool result = helper.Reflection.GetMethod(api, "GetThing").Invoke<bool>("boop");
</source>

Notes:
* You can't call <tt>GetApi</tt> until all mods are initialised and their <tt>Entry</tt> methods called. You can use the <tt>GameEvents.FirstUpdateTick</tt> [[#Events|event]] if you need to access mod APIs early; this is guaranteed to happen after all mods are initialised.
* You should always null-check APIs you consume. <tt>GetApi</tt> will return <tt>null</tt> if the API isn't available (e.g. because the mod isn't already installed or doesn't have one), or if an error occurs fetching the API.
translators
8,404

edits

Navigation menu