Dynamically combine classes in order to remove responsibilities from API - c#

I'm building an API (for a game-engine) which exposes two interfaces called IWindow and IEngineWindow.
The IWindow interface is supposed to be implemented by an API-user and the IEngineWindow interface is used by the engine to interact with the window.
The window object should have a private member of the type List<IWindowControl>.
I could use an abstract class and get rid of the interfaces but then i would have implementation-details in my API which i don't want.
My theoretical solution to the problem is that the API-user implements IWindow in his own class and calls a method (something like GetEngineWindow(typeof(MyWindowClass))) which returns an object which is identical to an instance of MyWindowClass except that it also implements the IEngineWindow interface.
I was planning to use System.Reflection.Emit in the GetEngineWindow() method to dynamically combine MyWindowClass with an internal class which implements the IEngineWindow interface but i quickly realised that this would be a mayor project of it's own.
My question boils down to if there is a simpler solution to remove this kind of implementation-details from an API or if there exists a library (free for commercial use) to do this kind of class-fusing.
In case my question is too abstract, here is a code example of what i want to be able to do:
//API (dll-file)
interface IWindow
{
void BeforeClose();
}
interface IEngineWindow
{
void Show();
}
//Built into engine (written by me)
class Program
{
static void Main(string[] args)
{
object window = CombineClasses(typeof(Testwindow), typeof(EngineWindow));
((IWindow)window).BeforeClose(); //Outputs: Closing...
((IEngineWindow)window).Show(); //Outputs: Showing window...
}
}
class EngineWindow : IEngineWindow
{
public void Show()
{
Console.WriteLine("Showing window...");
}
}
//External assembly (dll-file)
class Testwindow : IWindow
{
public void BeforeClose()
{
Console.WriteLine("Closing...");
}
}

This sounds like you need a wrapper.
Let your internal class take an IWindow instance in its constructor
store it in a private field
implement both interfaces
and forward all IWindow members to the internal instance
Update: if you consider CastleWindsor a simpler approach, here it is (using xUnit for tests):
namespace Mixins
{
using System;
using Castle.DynamicProxy;
using Xunit;
public interface IA
{
void Do();
}
public interface IB
{
void Something();
}
public class A : IA
{
public void Do()
{
throw new NotImplementedException("A");
}
}
public class B : IB
{
public void Something()
{
throw new NotImplementedException("B");
}
}
public class Blender
{
[Fact]
public void Mix()
{
var options = new ProxyGenerationOptions();
// the instances for A and B would be the user provided and yours
options.AddMixinInstance(new A());
options.AddMixinInstance(new B());
var proxy = new ProxyGenerator().CreateClassProxy<object>(options);
Assert.IsAssignableFrom<IA>(proxy);
Assert.IsAssignableFrom<IB>(proxy);
try
{
((IA)proxy).Do();
}
catch (NotImplementedException ex)
{
if (ex.Message != "A")
{
throw;
}
}
try
{
((IB)proxy).Something();
}
catch (NotImplementedException ex)
{
if (ex.Message != "B")
{
throw;
}
}
}
}
}

I am the author of NCop - A composite-aspect framework that can help you achieve your goal.
NCop wiki
You basically need to create a new composite type interface that will implement both of your window interfaces and mark it as a composite using the TransientComposite attribute.
[TransientComposite]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
Order NCop to match between interfaces and implementations using Mixins attribute.
[TransientComposite]
[Mixins(typeof(EngineWindow), typeof(Testwindow))]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
create a CompositeContainer that will emit the new type.
class Program
{
static void Main(string[] args) {
ICompositeWindow window = null;
var container = new CompositeContainer();
container.Configure();
window = container.Resolve<ICompositeWindow>();
window.Show();
window.BeforeClose();
}
}
your final code should be:
using System;
using NCop.Composite.Framework;
using NCop.Mixins.Framework;
using NCop.Composite.Runtime;
namespace NCop.Samples
{
[TransientComposite]
[Mixins(typeof(EngineWindow), typeof(Testwindow))]
public interface ICompositeWindow : IWindow, IEngineWindow
{
}
public interface IWindow
{
void BeforeClose();
}
public interface IEngineWindow
{
void Show();
}
public class EngineWindow : IEngineWindow
{
public void Show() {
Console.WriteLine("Showing window...");
}
}
public class Testwindow : IWindow
{
public void BeforeClose() {
Console.WriteLine("Closing...");
}
}
class Program
{
static void Main(string[] args) {
ICompositeWindow window = null;
var container = new CompositeContainer();
container.Configure();
window = container.Resolve<ICompositeWindow>();
window.Show();
window.BeforeClose();
}
}
}

Related

How Can I access base class method having same name in derived class using derived class object

I have a base class implementing an interface and further a specialized class inheriting the base class.
I have implemented interface's method in base class and marked it as virtual, also overridden the same method in specialized class.
Now i want to resolve the method GetData() on some basis that it either returns base class's method or child class's method.
So basically how can I call base class method using the specialized class's reference or interface's reference?
Edit 1
I have an existing data provider and I want to keep its functionality as it is and want to use some subclass or wrapper class where i can write a new implementation(another provider), mind that I want to keep running existing provider as it is for existing scenario and the new provider for other scenarios). what if i use decorator pattern to solve this? Any other pattern which can solve this ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
Console.ReadLine();
}
}
}
This is the only solution I could come up with for your problem:
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
if (dataprovider is ManagedDataProvider)
{
(dataprovider as ManagedDataProvider).GetBaseData();
}
Console.ReadLine();
}
}
Another Way to attack it is adding GetBaseData to the Interface.
interface IDataProvider
{
void GetData();
void GetBaseData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
public virtual void GetBaseData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public override void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
dataprovider.GetBaseData();
Console.ReadLine();
}
}

C# polymorphous design without casting

I have Generator class that generates objects with different Interfaces with different probabilities. All objects generated by Generator is of type BaseClass. BaseClass is an abstract base class.
Lets say interfaces are I1, I2
I have another class Resolver that has polymorphic method for two interfaces as follows:
Resolve(I1 myObj){//code for I1}
Resolve(I2 myObj){//code for I2}
The main class looks like this:
BaseClass event = Generator.generate(); //event is implements I1 or I2. Not known what interfaces until run time.
Resolver.Resolve(event); //Here i got an error, because event is BaseClass type and not I1 or I2 type.
Is there a way to solve this issue without explicitly check Interface type and cast it to appropriate interface. I came from python background, so statically typed language is new for me.
Consider using dependency injection to allow the event object to call the Resolver itself.
public interface IResolvable
{
void Resolve(Resolver resolver);
}
public interface I1 : IResolvable { //... }
public interface I2 : IResolvable { //... }
public class Resolver
{
public void Resolve(I1 i) { //... }
public void Resolve(I2 i) { //... }
}
public abstract class BaseClass : IResolvable
{
public abstract void Resolve(Resolver resolver);
//...
}
An implementation would look something like:
public class Implementation1 : BaseClass, I1
{
public override void Resolver(Resolver resolver)
{
resolver.Resolve(this);
}
//...
}
And then calling it:
Resolver resolver = new Resolver();
IResolvable evnt = Generator.Generate();
evnt.Resolve(resolver);
We can go a step further and make an interface for Resolver, so we can mock it for unit testing purposes and take full advantage of the DI pattern.
public interface IResolver
{
void Resolve(I1 i) { //... }
void Resolve(I2 i) { //... }
}
Then we change the definition of IResolvable
public interface IResolvable
{
void Resolve(IResolver resolver);
}
Here is some code that demonstrates virtual function approach that doesn't need casting.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
interface IBase
{
void Function();
}
class BaseClass : IBase
{
public virtual void Function()
{
}
}
interface I1: IBase
{
}
interface I2 : IBase
{
}
class C1: BaseClass, I1
{
public override void Function()
{
Console.WriteLine("Hello from C1");
}
}
class C2 : BaseClass, I1
{
public override void Function()
{
Console.WriteLine("Hello from C2 !!!");
}
}
static class Generator
{
public static BaseClass generateC1()
{
return new C1();
}
public static BaseClass generateC2()
{
return new C2();
}
}
class Program
{
static void Main(string[] args)
{
BaseClass b1 = Generator.generateC1();
b1.Function();
Console.WriteLine("-------");
BaseClass b2 = Generator.generateC2();
b2.Function();
Console.WriteLine("End!");
}
}
}
EDIT I adjusted my answer because I did not understand the question correctly the first time.
I think that you can not achieve exactly what you would like to without using casts. As far as I understand as soon as you reference the object you get from Generator.generate() by its base type it is not possible to access the object by its specialized type again without casting it.
I can think of two alternatives which might be interesting for you. One is using C# 7 pattern matching (which is a bit like using casts) and the other is using dynamic.
Pattern matching
using System;
namespace EventREsolver
{
public interface IEvent { }
public class Event1 : IEvent { }
public class Event2 : IEvent { }
public class Resolver
{
public void Resolve(IEvent theEvent)
{
switch (theEvent)
{
case Event1 e1: Resolve(e1); break;
case Event2 e2: Resolve(e2); break;
default: throw new ArgumentException("not a recognized type", nameof(theEvent));
}
}
private void Resolve(Event1 theEvent)
{
Console.WriteLine("Resolve I1");
}
private void Resolve(Event2 theEvent)
{
Console.WriteLine("Resolve I2");
}
}
public class Generator
{
int state = 0;
public IEvent Generate()
{
if (state == 0)
{
state++;
return new Event1();
}
return new Event2();
}
}
class Program
{
static void Main(string[] args)
{
var generator = new Generator();
var event1 = generator.Generate();
var event2 = generator.Generate();
var resolver = new Resolver();
resolver.Resolve(event1);
resolver.Resolve(event2);
Console.ReadKey();
}
}
}
Dynamic
using System;
namespace EventREsolver
{
public interface IEvent { }
public class Event1 : IEvent { }
public class Event2 : IEvent { }
public class Resolver
{
public void Resolve(Event1 theEvent)
{
Console.WriteLine("Resolve I1");
}
public void Resolve(Event2 theEvent)
{
Console.WriteLine("Resolve I2");
}
}
public class Generator
{
int state = 0;
public IEvent Generate()
{
if (state == 0)
{
state++;
return new Event1();
}
return new Event2();
}
}
class Program
{
static void Main(string[] args)
{
var generator = new Generator();
dynamic event1 = generator.Generate();
dynamic event2 = generator.Generate();
var resolver = new Resolver();
resolver.Resolve(event1);
resolver.Resolve(event2);
Console.ReadKey();
}
}
}

Collection of generic handlers - is this possible?

Using generics is it possible to have a generic collection defined as a base type and assign instances of a sub type? I have a simple code sample below that highlights my thinking and the line that causes the compiler error. I know that I could create a IEventHandler marker interface and make my generic event handlers inherit from that. This would let me store the generic types within a collection of IList, but this seems less than ideal. Is there a way similar to the code I have below?
using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
IEventHandler<SomeEvent1> handler1 = new SomeEvent1Handler();
IEventHandler<SomeEvent2> handler2 = new SomeEvent2Handler();
IList<IEventHandler<IEvent>> handlers = new List<IEventHandler<IEvent>>();
// COMPILE ERROR - is this possible?
handlers.Add(new SomeEvent1Handler());
}
public interface IEvent {
}
public interface IEventHandler<in TEvent> where TEvent : IEvent
{
void Handle(TEvent someEvent);
}
public class SomeEvent1 : IEvent {
}
public class SomeEvent2 : IEvent {
}
public class SomeEvent1Handler : IEventHandler<SomeEvent1>
{
public void Handle(SomeEvent1 someEvent)
{
throw new NotImplementedException();
}
}
public class SomeEvent2Handler : IEventHandler<SomeEvent2>
{
public void Handle(SomeEvent2 someEvent)
{
throw new NotImplementedException();
}
}
}
}
Using generics is it possible to have a generic collection defined as
a base type and assign instances of a sub type?
Yes, but It could only be done if your interface was IEventHandler<out TEvent>, you can't do it with in.
If your code did work, what would you expect to happen if the code was
public static void Main(string[] args)
{
IList<IEventHandler<IEvent>> handlers = new List<IEventHandler<IEvent>>();
handlers.Add(new SomeEvent1Handler()); //Magicly works
IEventHandler<IEvent> handler = handlers[0];
handler.Handle(new SomeEvent2());
}
handler states it allows any IEvent to be passed in to its Handle function. This would cause SomeEvent1Handler would be passed a SomeEvent2 object to its public void Handle(SomeEvent1 someEvent) method.
My work around would be have the handlers just take in a IEvent, in the function they check if it is a type of event they don't care about they can just return from the function without doing anything.
using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
IEventHandler<SomeEvent1> handler1 = new SomeEvent1Handler();
IEventHandler<SomeEvent2> handler2 = new SomeEvent2Handler();
IList<IEventHandler> handlers = new List<IEventHandler>();
handlers.Add(new SomeEvent1Handler());
}
public interface IEvent {
}
public interface IEventHandler
{
void Handle(IEvent someEvent);
}
public class SomeEvent1 : IEvent {
}
public class SomeEvent2 : IEvent {
}
public class SomeEvent1Handler : IEventHandler
{
public void Handle(IEvent someEvent)
{
var event = someEvent as SomeEvent1;
if(event == null)
return;
//Do stuff here.
}
}
public class SomeEvent2Handler : IEventHandler
{
public void Handle(IEvent someEvent)
{
var event = someEvent as SomeEvent2;
if(event == null)
return;
//Do stuff here.
}
}
}
}
This cannot be done as it is not safe - if it were allowed you could do:
var handlers = new List<IEventHandler<IEvent>> { new SomeEvent1Handler() };
handlers[0].Handle(new SomeEvent2());
I suggest you create a wrapper class around a typed handler e.g.
public class HandlerWrapper<T> : IEventHandler<IEvent>
{
private readonly IEventHandler<T> inner;
public HandlerWrapper(IEventHandler<T> inner)
{
this.inner = inner;
}
public void Handle(IEvent event)
{
if(event is T) { inner.handle((T)event); }
else throw new ArgumentException("Unexpected event type");
}
}
You can now create an IList<EventHandler<IEvent>> and you will need to manage the dispatch to the correct handler dynamically.

Implement method in another project

Is it possible to declare a method's class in a project and implement in another ? Something like :
namespace projectA
{
Class A
{
void toImplement()
{
//TODO
}
void print()
{
toImplement();
}
}
}
namespace projectB
{
A.toImplement()
{
// print “projectB"
}
}
namespace projectC
{
A.toImplement()
{
// print “projectC"
}
}
I don't want to create a new class with inheritance, because I want to use the method in class A. But if I define the method in a project K, the method will do the same that if I call from project B.
You can create an abstract method, but it will have to be public to be accessible in another project:
namespace projectA
{
public abstract Class A
{
public abstract void toImplement();
}
}
namespace projectB
{
public Class B : A
{
public override void toImplement()
{
//Implement here
}
}
}
You can write an Extension function see MSDN: Extension Function
For just adding methods to it, - as you described in your second code example - you could use a partial class
public static class B_Extensions
{
public static void SetString(this A a, string s)
{
a.Astring = s;
}
}
public class A
{
public string Astring { get; set; }
}
// In any other class
private void DoSomething()
{
var a = new A();
a.SetString("Something");
}
Partial Class: - put those in the same project
public partial class A
{
public void SetString(string s)
{
Astring = s;
}
}
public partial class A
{
public string Astring { get; set; }
}
So my guess is the reason you don't want to make A abstract and implement it in the other projects is because you want to be able to do new A() in the library.
In this case, the solution therefore, is to use the Factory Pattern.
You make the method abstract, and you declare a factory interface.
namespace projectA {
Class A
{
abstract void toImplement();
}
Interface AFactory
{
A create()
}
}
Then in your project that uses this you have your implementation of A and make a factory.
namespace projectB
{
Class RealA extends A
{
void toImplement() { does stuff }
}
Class RealAFactory implements AFactory
{
A create() { return new RealA() }
}
}
You now just need to pass the factory to the library when initalising it or at some logically point in time. Now projectA can get a new instance of RealA whenever it needs from RealAFactory.

simulating multiple inheritance in C#

so i saw this example from stackoverflow
to implement multiple inheritance by using interfaces.
interface ILARGESimulator
{
}
interface IUDPClient
{
}
class UDPClient : IUDPClient
{
}
class LargeSimulator : ILARGESimulator
{
}
class RemoteLargeSimulatorClient : IUDPClient, ILargeSimulator
{
private IUDPClient client = new UDPClient();
private ILARGESimulator simulator = new LARGESimulator();
}
The guy said
"Unfortunately you will need to write wrapper methods to the members. Multiple inheritance in C# does not exist. You can however implement multiple interfaces."
Why do we inherit from both interfaces anyway?
class RemoteLargeSimulatorClient : IUDPClient, ILargeSimulator
If you are having a has-a relationship and calling the base objects on the derived class, why do even have to write :IUDP, ILargeSimulator?
wouldn't it be simply
class RemoteLargeSimulatorClient
{
is good?
If you don't base the class on the interfaces then you can't pass it as a IUDPClient or ILargeSimulator to other code. When he said you need to add the implentations manually he was basically suggesting you do this:
interface ILargeSimulator
{
void Simulator_Method_1();
void Simulator_Method_2();
}
public class UDPClient : IUDPClient
{
public void UDPClient_Method_1() { /* do something here */ }
public void UDPClient_Method_2() { /* do something here */ }
}
interface IUDPClient
{
void UDPClient_Method_1();
void UDPClient_Method_2();
}
public class LargeSimulator : ILargeSimulator
{
public void Simulator_Method_1() { /* do something here */ }
public void Simulator_Method_2() { /* do something here */ }
}
public class RemoteLargeSimulatorClient : IUDPClient, ILargeSimulator
{
private IUDPClient client = new UDPClient();
private ILargeSimulator large = new LargeSimulator();
public void Simulator_Method_1() { this.large.Simulator_Method_1(); }
public void Simulator_Method_2() { this.large.Simulator_Method_2(); }
public void UDPClient_Method_1() { this.client.UDPClient_Method_1(); }
public void UDPClient_Method_2() { this.client.UDPClient_Method_2(); }
}
Then you can create an object instance of RemoteLargeSimulatorClient and use it as either a ILargeSimulator or IUDPClient:
static void DoSomethingWithClient(IUDPClient client) { /* etc */ }
static void DoSomethingWithSimulator(ILargeSimulator simulator) { /* etc */ }
static void Main(string[] args)
{
RemoteLargeSimulatorClient foo = new RemoteLargeSimulatorClient();
DoSomethingWithClient(foo);
DoSomethingWithSimulator(foo);
}
Multiple class inheritance does not exist in C#. Otherwise can be inherit from multiple interfaces. Your example is try solve multiple class inheritance.
First you full understand an Interface. Why are interfaces useful

Categories

Resources