EllanJiang/GameFramework · error · GameFrameworkException
You must get module by interface, but
Error message
You must get module by interface, but '{0}' is not. What it means
GameFrameworkEntry.GetModule<T> requires T to be an interface so it can locate the concrete implementation class by naming convention (IWebRequestAgent -> WebRequestAgent, etc.). Passing a class or struct as T breaks that lookup, so it throws GameFrameworkException immediately.
Solutions
- Pass the interface type instead, e.g. GetModule<IWebRequestAgent>-style: GetModule<IEvent>() not GetModule<Event>().
- Define an interface for your custom module if it doesn't have one, and request that interface.
- Check the using directives — a same-named class from another namespace may be resolved instead of the interface.
- Verify the type argument is one of the GameFramework module interfaces (IEvent, IUI, IResource, etc.).
Example fix
// before var eventComponent = GameFrameworkEntry.GetModule<Event>(); // after var eventComponent = GameFrameworkEntry.GetModule<IEvent>();
Defensive patterns
Strategy: type-guard
Validate before calling
var t = typeof(T); if (!t.IsInterface) throw new ArgumentException("GetModule<T> requires an interface type: " + t.FullName); Type guard
static bool IsModuleInterface<T>() where T : class => typeof(T).IsInterface && typeof(T).FullName.StartsWith("GameFramework.", StringComparison.Ordinal); Try / catch
try { var mod = GameFrameworkEntry.GetModule<T>(); } catch (GameFrameworkException ex) { Log.Fatal("GetModule requires an interface: {0}", ex.Message); throw; } Prevention
- Always request modules via their I-prefixed interfaces (IEvent, IUI, IResource)
- Check the resolved type in IntelliSense — a same-named class may shadow the interface
- Create an interface for custom modules before registering them
When it happens
Trigger: Calling GetModule<SomeClass>() where typeof(T).IsInterface is false — e.g. GetModule<WebRequest>() or GetModule<DefaultLogHelper>() instead of the corresponding interface.
Common situations: IDE auto-import picking the concrete type instead of the GameFramework interface; refactoring that merged an interface into a class; new developers requesting a helper class directly rather than its interface; copying a GetModule call and editing the generic argument to a non-module type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Already exist ' ' in data table ' '.
- Already exist FSM ' '.
- Apply resources complete callback is invalid.
- Asset is invalid.
- Binary asset name is invalid.
AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15).
Data as JSON: /api/errors/08ffde7d09b34f63.
Report an issue: GitHub.
Appendix: source
Thrown at GameFramework/Base/GameFrameworkEntry.cs:60
s_GameFrameworkModules.Clear();
ReferencePool.ClearAll();
Utility.Marshal.FreeCachedHGlobal();
GameFrameworkLog.SetLogHelper(null);
}
/// <summary>
/// 获取游戏框架模块。
/// </summary>
/// <typeparam name="T">要获取的游戏框架模块类型。</typeparam>
/// <returns>要获取的游戏框架模块。</returns>
/// <remarks>如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。</remarks>
public static T GetModule<T>() where T : class
{
Type interfaceType = typeof(T);
if (!interfaceType.IsInterface)
{
throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
}
if (!interfaceType.FullName.StartsWith("GameFramework.", StringComparison.Ordinal))
{
throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", interfaceType.FullName));
}
string moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name.Substring(1));
Type moduleType = Type.GetType(moduleName);
if (moduleType == null)
{
throw new GameFrameworkException(Utility.Text.Format("Can not find Game Framework module type '{0}'.", moduleName));
}
return GetModule(moduleType) as T;
}
/// <summary>View on GitHub (pinned to d0c010b051)