Type Pool
342 words · 2 minute read

The Type Pool concept comes from working with the Fubu code base its a pretty simple class that I find makes type scanning much simpler.

{{< highlight csharp >}} namespace v23athletics.infrastructure.types { using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Fasterflect;

public class TypePool { readonly IList<Assembly> _assemblies; Lazy<IEnumerable<Type>> _types;

public TypePool(params Assembly[] assemblies) { _assemblies = new List<Assembly>(assemblies); _types = new Lazy<IEnumerable<Type>>(buildUp); } public TypePool() : this(new Assembly[0]) { }

public Assembly[] Assemblies { get { return _assemblies.ToArray(); } }

//add a source to scan. public void AddSource(Assembly assembly) { _assemblies.Add(assembly); _types = new Lazy<IEnumerable<Type>>(buildUp); }

//for LINQ queries public IEnumerable<Type> Query() { return _types.Value; }

//if you want to have the scans be seperate testable classes public IEnumerable<Type> Scan<TScanner>() where TScanner : TypeScan, new() { var scanner = new TScanner(); return _types.Value.Where(scanner.Matches); }

public IEnumerable<Type> Scan(Func<Type, bool> predicate) { return _types.Value.Where(predicate); }

//function to build the types up lazily IEnumerable<Type> buildUp() { return _assemblies.SelectMany(a => a.ExportedTypes); }

public IEnumerable<Type> FindImplementorsOf<TInterface>() { return Scan(t => t.Implements<TInterface>()); } }

} {{< /highlight >}}

{{< highlight csharp >}}

var typePool = new TypePool(typeof(MarkerType).Assembly); var settingTypes = typePool.Query().Where(t=>t.Name.EndsWith("Settings"));

{{< /highlight >}}

I use this guy to help me find types so that i can register them in my IoC container. Now most containers have their own scanning conventions, but one thing they tend to lack is a way to pass around the 'Application Assemblies' which is is something the TypePool can do. By passing the TypePool into the lower services or IoC 'Registries' I can use there scanning capabilities or I can use my own.

{{< highlight csharp >}}

public class MySubRegistry : Registry { public MySubRegistry(TypePool pool) { Scan(scanner => { scanner.AddAllTypes<IService>(); foreach(var ass in pool.Assemblies) scanner.Assembly(ass); }) } }

public class MySubModule : Module { TypePool _pool;

public MySubModule(TypePool pool) { _pool = pool; }

public void RegisterComponents(ContainerBuilder builder) { var types = _pool.Query().Where( t => t.Implements<IService>()); builder.RegisterTypes(types) .As<IService>(); } } } {{< /highlight >}}

My name is Dru Sellers. I’m an engineering leader and architect that focuses on building and modernizing product systems in growing companies, with an emphasis on reliability, scalability, and strong engineering practices.

Content on this site is licensed under a Creative Commons Attribution 4.0 International License.