using static System.Console;
public class Cat { public void Meow(){ Write("Meow"); } }
public class Dog { public void Woof(){ Write("Woof"); } }
public class Pig { public void Oink(){ Write("Oink"); } }
public interface ICatLocator { Cat cat { get; } }
public interface IDogLocator { Dog dog { get; } }
public interface IPigLocator { Pig pig { get; } }
public class ServiceLocator : ICatLocator, IDogLocator, IPigLocator {
public Cat cat => new Cat();
public Dog dog => new Dog();
public Pig pig => new Pig();
public abstract class ClientCode {
protected abstract Cat cat { get; }
protected abstract Dog dog { get; }
public ClientCode (int arg) {
public static ClientCode Create<TLocator>(TLocator locator, int arg) where TLocator : ICatLocator, IDogLocator {
return new ClientCode<TLocator>(locator, arg);
public class ClientCode<TLocator> : ClientCode where TLocator : ICatLocator, IDogLocator {
protected override Cat cat { get; }
protected override Dog dog { get; }
public ClientCode (TLocator locator, int arg) : base(arg) {
public class ClientCodeFactory {
private readonly ServiceLocator locator;
public ClientCodeFactory (ServiceLocator locator) {
public ClientCode Create (int arg) => new ClientCode<ServiceLocator>(locator, arg);
class Deps : ICatLocator, IDogLocator {
public Cat cat => new Cat();
public Dog dog => new Dog();
public static void Main () {
var factory = new ClientCodeFactory(new ServiceLocator());
factory.Create(42).Logic();
var cc2 = ClientCode.Create(new Deps(), 42);
var cc = new ClientCode<Deps>(new Deps(), 42);