could someone please help with the best way of returning the concrete implementation in the following scenarios. Say I have:
public interface IThing<TInput> where TInput : RequestBase
{
string Process(T input);
}
And then multiple implementations:
public class Thing1<T> : IThing<T> where T : ReqThing1
public class Thing2<T> : IThing<T> where T : ReqThing2
In my calling class what is the best way of wrapping the construction of those classes and returning the IThing that I want in a clean, testable way? Thanks
I don't quite understand what you want, but here's an idea:
public abstract class RequestBase
{
}
public class ReqThing1 : RequestBase
{
}
public class ReqThing2 : RequestBase
{
}
public interface IThing<T> where T : RequestBase
{
string Process(T input);
}
public class Thing1 : IThing<ReqThing1>
{
public string Process(ReqThing1 input)
{
throw new System.NotImplementedException();
}
}
public class Thing2 : IThing<ReqThing2>
{
public string Process(ReqThing2 input)
{
throw new System.NotImplementedException();
}
}
public class Program
{
public static void Main(string[] args)
{
var thing1 = new Thing1();
var thing2 = new Thing2();
}
}
Related
I'm trying to understand how Variance works. I have created a IRegistry interface which supports a Contravarint TDomainEvent and a Contravariant TDomainContraVariant. The thing is that the TDomainEvent extends a IDomainEvent and the TDomainContraVariant extends an IDomainEventHandler<TDomainEvent>.
For some reason I get errors saying that it is not possible to convert TDomainContraVariant to IDomainEventHandler<IDomainEvent>, which should be possible as a TDomainEvent extends an IDomainEvent.
using System;
using System.Collections.Generic;
public interface IDomainEvent {}
public class ProductSetCreatedEvent : IDomainEvent {}
public class VersionCreatedEvent : IDomainEvent {}
public class ProductSetCreatedEventHandler : IDomainEventHandler<ProductSetCreatedEvent> {}
public class VersionCreatedEventHandler : IDomainEventHandler<VersionCreatedEvent> {}
public interface IDomainEventHandler<in TDomainEvent> where TDomainEvent : IDomainEvent {}
public interface IRegistry<in TDomainEvent, in TDomainContraVariant>
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
void Add(TDomainContraVariant element);
}
public class Registry<TDomainEvent, TDomainContraVariant> : IRegistry<TDomainEvent, TDomainContraVariant>
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
private IList<IDomainEventHandler<IDomainEvent>> list;
public Registry()
{
this.list = new List<IDomainEventHandler<IDomainEvent>>();
}
public void Add(TDomainContraVariant element)
{
this.list.Add(element);
}
public IList<IDomainEventHandler<IDomainEvent>> Get()
{
return this.list;
}
}
public class Program
{
private static Registry<IDomainEvent, IDomainEventHandler<IDomainEvent>> list = new Registry<IDomainEvent, IDomainEventHandler<IDomainEvent>>();
public static void Main()
{
IDomainEventHandler<ProductSetCreatedEvent> eventHandler = new ProductSetCreatedEventHandler();
AddToRegistry<ProductSetCreatedEvent, IDomainEventHandler<ProductSetCreatedEvent>>(eventHandler);
}
public static void AddToRegistry<TDomainEvent, TDomainContraVariant>(TDomainContraVariant cesto)
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
list.Add(cesto);
}
}
I am reshaping an entire system that does not use base classes and base interfaces.
My idea to do so is to extract all the common methods to a base classes and base interfaces.
So basically, we would have:
A base class SomeClassBase implementing an interface ISomeClassBase
A derived class SomeClassDerived implementing ISomeClassDerived (this interface deriving from ISomeClassBase)
Now the problem, how can I instantiate "_mySession" in the derived class (which has a different cast than in the base class), while preserving all the methods from the base class:
public class SomeClassBase : ISomeClassBase
{
public IMySessionBase _mySession = MySession.Instance();
public SomeClassBase ()
{
_mySession.connect(); // Needed??
}
public void doSomething()
{
_mySession.doSomething();
}
}
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
public IMySessionDerived _mySession = MySession.Instance();
public SomeClassDerived ()
{
_mySession.connect();
}
public void doSomethingElse()
{
_mySession.doSomethingElse();
}
}
One more thing, IMySessionDerived implements IMySessionBase.
Do not redefine _mySession Let it come from base class.
However in you Derived class you can still reassign.
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
public SomeClassDerived ()
{
_mySession = MySession.Instance(); //Declaration comes from base class automatically
_mySession.connect();
}
public void doSomethingElse()
{
_mySession.doSomethingElse();
}
}
If your IMySessionBase and IMySessionDerived are following Hierarchy, it should work. But in some rare cases, You might end up getting into a DoubleDispatchProblem.
As Pointed out in commens, If you want to do something from IMySessionDerived you can add a Property.
public class SomeClassDerived : SomeClassBase, ISomeClassDerived
{
IMySessionDerived _derivedSessionAccessor=> _mySession as IMySessionDerived;
}
Update: To fix the exact design problem here,
Instead of deriving from the base class, have it as a field. And inherit from interface. So Instead of doing above approach,
do like,
public class SomeClassBase : ISomeClassBase
{
public IMySessionBase _mySession ;
public SomeClassBase ( IMySessionBase session)
{
_mySession=session;
_mySession.connect(); // Needed??
}
public void doSomething()
{
_mySession.doSomething();
}
}
public class SomeClassDerived : , ISomeClassDerived
{
public IMySessionDerived _mySession = MySession.Instance();
private SomeClassBase _baseClassInstance;
public SomeClassDerived ()
{
_baseClassInstance=new SomeClassBase(_mySession);
//_mySession.connect();
}
public void doSomethingElse()
{
_baseClassInstance.doSomethingElse();
}
}
Pasting #Selvin answer instead of the link buried in the comments:
The trick here is to use the keyword "base()"
using System;
using System.Runtime.CompilerServices;
public class Program
{
public static void Main()
{
var o1 = new O1();
o1.DS1();
var o2 = new O2();
o2.DS1();
o2.DS2();
}
public class Session1
{
protected readonly Type ownerType;
public Session1(Type type)
{
ownerType = type;
}
public virtual void DS1([CallerMemberName] string functionName = "")
{
Console.WriteLine(ownerType.Name + ":" + GetType().Name + ":" + functionName);
}
}
public class Session2 : Session1
{
public Session2(Type type):base(type) { }
public virtual void DS2([CallerMemberName] string functionName = "")
{
Console.WriteLine(ownerType.Name + ":" + GetType().Name + ":" + functionName);
}
}
public class O1
{
private readonly Session1 t;
public O1() : this(new Session1(typeof(O1))) { }
protected O1(Session1 t)
{
this.t = t;
}
public void DS1()
{
t.DS1();
}
}
public class O2 : O1
{
private readonly Session2 t;
public O2() : this(new Session2(typeof(O2))) { }
protected O2(Session2 t) : base(t)
{
this.t = t;
}
public void DS2()
{
t.DS2();
}
}
}
I'm not sure if this is possible, I've seen some other posts asking similar question but none have a satisfactory answer.
What I want to do is resolve a collection of interfaces with differing generic types from Autofac. So constructor of class would look something like this:
public class SomeClass<T> where T : class
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
}
Ideally, I'd just like to be able to register each instance individually like so:
builder
.RegisterType<ImplementationA>()
.As<ITestInterface<A>>();
builder
.RegisterType<ImplementationB>()
.As<ITestInterface<B>>();
I've tried various combinations of RegisterGeneric etc but the Enumerable just keeps coming through empty.
Any help would be appreciated.
I was able to resolve this after playing with inheritance & generic constraints. The solution I ended up with looks like this:
Base classes / interfaces:
public abstract class BaseClass
{
public abstract string IAM { get; }
}
public interface ITestInterface<out T> where T : BaseClass
{
T GetSomething();
}
Implemented classes:
public class A : BaseClass
{
public override string IAM => "I AM TYPE A";
}
public class AInterface : ITestInterface<A>
{
public A GetSomething()
{
return new A();
}
}
public class B : BaseClass
{
public override string IAM => "I AM TYPE B";
}
public class BInterface : ITestInterface<B>
{
public B GetSomething()
{
return new B();
}
}
Class we want to resolve:
public interface ISomeClass
{
void DoSomething();
}
public class SomeClass<T> : ISomeClass where T : BaseClass
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
public void DoSomething()
{
foreach (var t in _testInterfaces)
{
var something = t.GetSomething();
Console.WriteLine(something.IAM);
}
}
}
And finally, Autofac configuration:
var builder = new ContainerBuilder();
builder
.RegisterType<SomeClass<BaseClass>>()
.AsSelf();
builder
.RegisterType<AInterface>()
.As<ITestInterface<BaseClass>>();
builder
.RegisterType<BInterface>()
.As<ITestInterface<BaseClass>>();
builder
.RegisterType<SomeClass<BaseClass>>()
.As<ISomeClass>();
var container = builder.Build();
var x = container.Resolve<ISomeClass>();
x.DoSomething();
Outputs:
I AM TYPE A
I AM TYPE B
Hope this helps someone in the future.
RegisterGeneric should work fine :
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>();
builder.RegisterGeneric(typeof(SomeClass<>))
.As(typeof(ISomeClass<>));
or
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>();
builder.RegisterGeneric(typeof(SomeClass<>))
.AsSelf();
You will find below a working sample :
public interface ISomeClass<T> where T : class
{
Int32 Count { get; }
}
public class SomeClass<T> : ISomeClass<T> where T : class
{
private readonly IEnumerable<ITestInterface<T>> _testInterfaces;
public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
{
_testInterfaces = testInterfaces;
}
public Int32 Count
{
get
{
return this._testInterfaces.Count();
}
}
}
public interface ITestInterface {}
public interface ITestInterface<T> : ITestInterface { }
public class A { }
public class B { }
public class TestImplementationA : ITestInterface<A> { }
public class TestImplementationB : ITestInterface<B> { }
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<TestImplementationA>()
.As<ITestInterface<A>>()
.As<ITestInterface>();
builder.RegisterType<TestImplementationB>()
.As<ITestInterface<B>>()
.As<ITestInterface>();
builder.RegisterGeneric(typeof(SomeClass<>))
.As(typeof(ISomeClass<>));
IContainer container = builder.Build();
var x = container.Resolve<ISomeClass<A>>();
Console.WriteLine(x.Count);
var z = container.Resolve<IEnumerable<ITestInterface>>();
}
}
Currently I'm having a trouble with instantiating an AbstractFactory. There are some classes:
abstract class ABase { }
class A1 : ABase { }
class A2 : ABase { }
abstract class BBase { }
class B1 : BBase
{
private readonly A1 _a;
public B1(A1 a)
{
_a = a;
}
}
class B2 : BBase
{
private readonly A2 _a;
public B2(A2 a)
{
_a = a;
}
}
abstract class FactoryBBase
{
abstract public BBase Create(ABase b);
}
class FactoryB1 : FactoryBBase
{
override public BBase Create(ABase b)
{
return new B1(b as A1);
}
}
class FactoryB2 : FactoryBBase
{
override public BBase Create(ABase b)
{
return new B2(b as A2);
}
}
class Runtime
{
public void ProcessA(ABase a)
{
//How should I choose a proper factory?
}
}
How do I instantiate a proper abstract factory in ProcessA method depending on the type of a? The thing is that I don't want to have a big if/else block.
how to instantiate a proper abstract factory in ProcessA method depending on the type of a?
To avoid big if/else block you can put all factories into a map, where key is the type of a and value is the implementation. in Java I would do this either by Spring or I would create a static code, that can initialize the map when the class is loaded.
do I use AbstractFactory pattern as it is supposed to be uesd?
IMHO yes.
You can use a lookup dictionary instead of a if-else/switch construct.
//classes used as markers
public interface IMarker {}
public class MarkerA : IMarker {}
public class MarkerB : IMarker {}
//classes to be created
public interface IData {}
public class DataA : IData {}
public class DataB : IData {}
//factory to call abstract factories (could use static here)
public class Factory
{
public IData Create(IMarker marker)
{
//lookup dictionary instead of if/switch
//func ensures instance is only created when required
var lookup = new Dictionary<Type, Func<DataFactoryBase>>()
{
{ typeof(MarkerA), () => new DataAFactory() },
{ typeof(MarkerB), () => new DataBFactory() },
};
//get factory by type and call constructor
return lookup[marker.GetType()]().Create();
}
}
//abstract factories
public abstract class DataFactoryBase
{
public abstract IData Create();
}
public class DataAFactory : DataFactoryBase
{
public override IData Create()
{
return new DataA();
}
}
public class DataBFactory : DataFactoryBase
{
public override IData Create()
{
return new DataB();
}
}
public static void Main()
{
//example will return DataA
IData data = new Factory().Create(new MarkerA());
}
How to implement abstract factory really depends on what you need. What you have there is indeed a proper implementation, but I think it's not exactly what you need since you want to do something differently dependending on the type or state of an instance of ABase.
The logic that analyses the type or state is exactly what I'd put into a factory.
abstract class ABase { }
class A1 : ABase { }
class A2 : ABase { }
public abstract class FactoryBBase
{
public abstract IProcessor Create(ABase a);
}
public class ConcreteFactory : FactoryBBase
{
override public IProcessor Create(ABase a)
{
// this is ugly for a large amount of ABase implementations of course
if (a is A1)
{
return new Runtime1();
}
if (a is A2)
{
return new Runtime2();
}
throw new NotSupportedException();
}
}
public interface IProcessor
{
void ProcessA(ABase a);
}
public class Runtime1 : IProcessor
{
public void ProcessA(ABase a)
{
// process away
}
}
public class Runtime2 : IProcessor
{
public void ProcessA(ABase a)
{
// process away differently
}
}
Multiple factory implementations come into play when you want the same type of ABase implementation to be processed by different types of Runtime/Processor depending on state that is outside of ABase.
I want to have a base class:
public class Base
{
public static T Instance
{
get
{
// do something to return new instance of inherit class from itself
}
}
}
Class1:
public class Class1 : Base
{
// method and properties here
public string Func1()
{
return 'class1';
}
}
Class2:
public class Class2 : Base
{
// method and properties here
public string Func1()
{
return 'class2';
}
}
I want it so that we can use Class1 or Class2 like this
public class Main
{
var a = Base<Class1>.Instance.Func1(); // return 'class1'
var b = Base<Class2>.Instance.Func1(); // return 'class2'
}
Please help me to do this.
This is not called dynamic but polymorphic. In this case achieved with generics. Your only remaining problem is calling the constructor, which becomes possible when you put a Type-constraint on <T>.
public class Base<T> where T : new()
{
public static T Instance
{
get
{
// do something to return new instance of inherit class from itself
return new T();
}
}
}
and then:
public class Class1 : Base<Class1> { ... }
public class Class2 : Base<Class2> { ... }
But note that a simpler solution could be achieved with virtual+override methods or with an interface.
Alternative suggestion with some tighter type constraints:
namespace My.Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Base<Class1>.Instance.Func1());
Console.WriteLine(Base<Class2>.Instance.Func1());
}
}
public abstract class Base
{
public abstract string Func1();
}
public sealed class Base<T> where T : Base, new()
{
public static T Instance
{
get { return new T(); }
}
}
public class Class1 : Base
{
public override string Func1() { return "class 1"; }
}
public class Class2 : Base
{
public override string Func1() { return "class 2"; }
}
}