Last active
October 17, 2022 13:15
-
-
Save paulvanbladel/2c5b6481481de64ea1ac17086c2a3c6f to your computer and use it in GitHub Desktop.
DI friendly factory pattern.
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 is how we want to consume the factory, here in the context of a razor page: | |
public class IndexModel : PageModel | |
{ | |
private readonly IShapeRendererFactory _shapeRendererFactory; | |
public IndexModel( IShapeRendererFactory shapeRendererFactory) | |
{ | |
_shapeRendererFactory = shapeRendererFactory; | |
} | |
public void OnGet() | |
{ | |
var render = _shapeRendererFactory.Create<CircleRenderer>(); | |
render.RenderMe(); | |
} | |
} | |
// this is how we can make the DI registrations: | |
builder.Services.AddSingleton<OtherDep>(); | |
builder.Services.AddSingleton<IShapeRenderer, CircleRenderer>(); | |
builder.Services.AddSingleton<IShapeRenderer, TriangleRenderer>(); | |
builder.Services.AddSingleton<IShapeRenderer, SquareRenderer>(); | |
builder.Services.AddSingleton<IShapeRendererFactory>(ctx => | |
{ | |
var shapeRendererImplementations = ctx.GetServices<IShapeRenderer>(); | |
var factories = new Dictionary<Type, Func<IShapeRenderer>>(); | |
foreach (var item in shapeRendererImplementations) | |
{ | |
factories.Add(item.GetType(), () => item); | |
} | |
return new ShapeRendererFactory(factories); | |
}); | |
public interface IShapeRendererFactory | |
{ | |
IShapeRenderer Create<T>() where T : class, IShapeRenderer; | |
} | |
public interface IShapeRenderer | |
{ | |
public void RenderMe(); | |
} | |
public class OtherDep { } | |
public class CircleRenderer : IShapeRenderer | |
{ | |
private readonly OtherDep otherDep; | |
public CircleRenderer(OtherDep otherDep) | |
{ | |
this.otherDep = otherDep; | |
} | |
public void RenderMe() | |
{ | |
Console.WriteLine("I'm a circle"); | |
} | |
} | |
public class TriangleRenderer : IShapeRenderer | |
{ | |
public void RenderMe() | |
{ | |
Console.WriteLine("I'm a triangle"); | |
} | |
} | |
public class SquareRenderer : IShapeRenderer | |
{ | |
public void RenderMe() | |
{ | |
Console.WriteLine("I'm a square"); | |
} | |
} | |
public class ShapeRendererFactory : IShapeRendererFactory | |
{ | |
private readonly Dictionary<Type, Func<IShapeRenderer>> _factories; | |
public ShapeRendererFactory(Dictionary<Type, Func<IShapeRenderer>> factories) | |
{ | |
_factories = factories; | |
} | |
public IShapeRenderer Create<T>() where T : class, IShapeRenderer | |
{ | |
if (!_factories.TryGetValue(typeof(T), out var factory)) | |
{ | |
throw new ArgumentOutOfRangeException($"{typeof(T).Name} is not Registered"); | |
} | |
return factory(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment