-
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new: allow providing custom assemblies to SimpleTypeBinder; move some…
… tests over to the test project; also resolve SchemaFormatter in DynamicObjectFormatterResolver
- Loading branch information
1 parent
d64f3d6
commit c3a2521
Showing
13 changed files
with
647 additions
and
701 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
namespace Ceras | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
|
||
/// <summary> | ||
/// A type binder is simple. It is responsible to converts a type to a string and back. | ||
/// For generic types it must do so by deconstructing the type though. So giving <see cref="List{int}"/> would return "System.Collections.List". | ||
/// </summary> | ||
public interface ITypeBinder | ||
{ | ||
string GetBaseName(Type type); | ||
Type GetTypeFromBase(string baseTypeName); | ||
Type GetTypeFromBaseAndArguments(string baseTypeName, params Type[] genericTypeArguments); | ||
} | ||
|
||
/// <summary> | ||
/// This simple type binder does two things: | ||
/// <para>- does the basic ITypeBinder thing (converting types to names, and back)</para> | ||
/// <para>- allows the user to add assemblies that will be searched for types</para> | ||
/// </summary> | ||
public class SimpleTypeBinder : ITypeBinder | ||
{ | ||
readonly HashSet<Assembly> _searchAssemblies = new HashSet<Assembly>(); | ||
|
||
/// <summary> | ||
/// Put your own assemblies in here for Ceras to discover them. If you don't and a type is not found, Ceras will have to look in all loaded assemblies (which is slow) | ||
/// </summary> | ||
public HashSet<Assembly> CustomSearchAssemblies { get; } = new HashSet<Assembly>(); | ||
|
||
public SimpleTypeBinder() | ||
{ | ||
// Search in framework | ||
foreach (var frameworkAsm in CerasSerializer._frameworkAssemblies) | ||
_searchAssemblies.Add(frameworkAsm); | ||
|
||
// Search in user code | ||
_searchAssemblies.Add(Assembly.GetEntryAssembly()); | ||
|
||
_searchAssemblies.RemoveWhere(a => a == null); | ||
} | ||
|
||
|
||
public string GetBaseName(Type type) | ||
{ | ||
if (type.IsGenericType) | ||
return type.GetGenericTypeDefinition().FullName; | ||
|
||
return type.FullName; | ||
} | ||
|
||
public Type GetTypeFromBase(string baseTypeName) | ||
{ | ||
foreach (var a in _searchAssemblies) | ||
{ | ||
var t = a.GetType(baseTypeName); | ||
if (t != null) | ||
return t; | ||
} | ||
|
||
foreach (var a in CustomSearchAssemblies) | ||
{ | ||
if (_searchAssemblies.Contains(a)) | ||
continue; // We've already searched there | ||
|
||
var t = a.GetType(baseTypeName); | ||
if (t != null) | ||
{ | ||
_searchAssemblies.Add(a); | ||
return t; | ||
} | ||
} | ||
|
||
// Oh no... did the user forget to add the right assembly?? | ||
// Lets search in everything that's loaded... | ||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) | ||
{ | ||
if (_searchAssemblies.Contains(a) || CustomSearchAssemblies.Contains(a)) | ||
continue; // We've already searched there | ||
|
||
var t = a.GetType(baseTypeName); | ||
if (t != null) | ||
{ | ||
_searchAssemblies.Add(a); | ||
return t; | ||
} | ||
} | ||
|
||
throw new Exception("Cannot find type " + baseTypeName + " after searching in all user provided assemblies and all loaded assemblies. Is the type in some plugin-module that was not yet loaded? Or did the assembly that contains the type change (ie the type got removed)?"); | ||
} | ||
|
||
public Type GetTypeFromBaseAndArguments(string baseTypeName, params Type[] genericTypeArguments) | ||
{ | ||
var baseType = GetTypeFromBase(baseTypeName); | ||
return baseType.MakeGenericType(genericTypeArguments); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.