Skip to content

Instantly share code, notes, and snippets.

@gnaeus
Last active May 29, 2017 12:41
Show Gist options
  • Save gnaeus/64636f9f3fc06f4dea88e9d9c47f32f7 to your computer and use it in GitHub Desktop.
Save gnaeus/64636f9f3fc06f4dea88e9d9c47f32f7 to your computer and use it in GitHub Desktop.
[C#] Helpers for Bastard Injection pattern
using System;
using System.Threading;
namespace BastardInjection
{
public abstract class Transient<T> where T : new()
{
public static T Instance => new T();
}
public abstract class Singleton<T> where T : new()
{
private static Lazy<T> Lazy = new Lazy<T>(true);
public static T Instance => Lazy.Value;
}
public abstract class Scoped<T> where T : class, new()
{
private static AsyncLocal<T> AsyncLocal = new AsyncLocal<T>();
public static T Instance => AsyncLocal.Value ?? (AsyncLocal.Value = new T());
}
}
// Example
namespace BastardInjection
{
public interface IConfiguration
{
string ConnectionString { get; }
}
public class Configuration : IConfiguration
{
public class Singleton : Singleton<Configuration> { }
public string ConnectionString { get; }
public Configuration()
{
ConnectionString = File.ReadAllText("Connections.config");
}
}
public interface IRepository
{
IQueryable Query();
}
public class Repository : IRepository
{
public class Scoped : Scoped<Repository> { }
private readonly IConfiguration _configuration;
public Repository(IConfiguration configuration)
{
_configuration = configuration;
}
public Repository() : this(
Configuration.Singleton.Instance)
{
}
public IQueryable Query()
{
throw new NotImplementedException();
}
}
public interface IService
{
void DoWork();
}
public class Service : IService
{
public class Transient : Transient<Service> { }
private readonly IConfiguration _configuration;
private readonly IRepository _repository;
public Service(IConfiguration configuration, IRepository repository)
{
_configuration = configuration;
_repository = repository;
}
public Service() : this(
Configuration.Singleton.Instance,
Repository.Scoped.Instance)
{
}
public void DoWork()
{
throw new NotImplementedException();
}
}
public class Controller
{
public class Transient : Transient<Controller> { }
private readonly IService _service;
private readonly IRepository _repository;
public Controller(IService service, IRepository repository)
{
_service = service;
_repository = repository;
}
public Controller() : this(
Service.Transient.Instance,
Repository.Scoped.Instance)
{
}
public void Action()
{
_service.DoWork();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment