Casting to a base class using generics - c#

I seem to have some trouble understanding generics in c#.
Basically i have a base class called ConfigWorker and a bunch of sub classes which should all use their own config class deriving from BaseConfig.
The ConfigWorker class i want to use should be determined dynamically during runtime given the name of the class as a parameter.
I can instantiate the sub class given it's name, but no matter what i try, i can't get the casting to a sensible base class to work.
Here's my code:
namespace DocumentHandler
{
public class BaseConfig
{
}
public class ConfigWorker<T> where T : BaseConfig
{
public virtual void Work(T options)
{
}
}
public class Worker1 : ConfigWorker<Worker1.Config>
{
public class Config : BaseConfig
{
public string test = "";
}
public override void Work(Config options)
{
//do something
}
}
public class Worker2 : ConfigWorker<Worker2.Config>
{
public class Config : BaseConfig
{
public string test = "";
}
public override void Work(Config options)
{
//do something else
}
}
public class Test
{
public static BaseConfig config;
public static void test()
{
(Activator
.CreateInstance(Type.GetType("DocumentHandler.Worker2"))
as ConfigWorker<BaseConfig>)
.Work(config);
}
}
}
The crucial line is
(Activator
.CreateInstance(Type.GetType("DocumentHandler.Worker2"))
as ConfigWorker<BaseConfig>)
.Work(config);
The casting to ConfigWorker<BaseConfig> returns null, as the cast can not be performed.
Trying to simply cast to ConfigWorker does not compile as the type parameter is missing.
Anything else i can try? CreateInstance obviously just returns an object and i need to cast that to be able to call the Work method
Any help is appreciated.

An instance of Worker2 is not a ConfigWorker<BaseConfig>! It's a ConfigWorker<Worker2.Config>. These are two totally different types. Generic classes are invariant. Only interfaces and delegates can be co- or contra-variant.
In your example, ConfigWorker is even contra-variant in T, meaning you use T as the type of an input parameter to a method. So what you try is actually dangerous.
Imagine your line would work: you get an variable of type ConfigWorker<BaseConfig>, so you could rely on this instance having a method Work() which takes a BaseConfig (or something derived from it) as argument. So nothing could stop you from calling it like
worker.Work(new Worker1.Config());
Compiles fine. But wait a moment! Didn't your line state that worker is a Worker2? Worker2 instances can only handle Worker2.Config arguments!
You completely loose type safety this way (well, you would if it was allowed).
There is a flaw in your class design.

This looks like a good problem that factory pattern has good good solution for.
Here is a simplified solution
namespace DocumentHandler
{
public interface IBaseConfig
{
}
public class ConfiManager : IBaseConfig
{
}
public abstract class WorkerFactory
{
private readonly IBaseConfig _config;
protected WorkerFactory(IBaseConfig config)
{
this._config = config;
}
public virtual void Work()
{
}
}
public class Worker1 : WorkerFactory
{
private readonly IBaseConfig _config;
public Worker1(IBaseConfig config):base(config)
{
_config = config;
}
public string test = "";
public override void Work()
{
//do something
}
}
public class Worker2 : WorkerFactory
{
private readonly IBaseConfig _config;
public string test = "";
public Worker2(IBaseConfig config):base(config)
{
this._config = config;
}
public override void Work()
{
Console.WriteLine("Hello world");
}
}
public class Test
{
public static IBaseConfig config = new ConfiManager();
public static void test()
{
WorkerFactory worker =
(Worker2) Activator.CreateInstance(Type.GetType("DocumentHandler.Worker2"), config);
worker.Work();
}
}
}

Related

Static class derive from base change member

In C# a static class can not derive from any other class besides object.
Currently I have this base class:
public static class BaseModule
{
public static string UsedSource {get; set;}
public static Write(string text)
{
OtherStaticClass.Log(UsedSource, text);
}
}
Now, depending on which class I'm using, I want to change UsedSource.
// this does not work
internal static class ModuleA : BaseModule
{
static ModuleA(){
UsedSource = "A" // just an example
}
}
// this does not work
internal static class ModuleB : BaseModule
{
static ModuleB(){
UsedSource = "B" // just an example
}
}
Supposed to be called like this
ModuleA.Write("Hi");
ModuleB.Write("Hi");
This approach does not work because a static class cannot derive from anything else than object.
Is there any other way to change the property?
You have a lot of static classes going on here and I'm not entirely sure they're necessary. My example does not use static classes other than for the OtherStaticClass reference you have. I understand this may not be quite what you're looking for; many ways to skin this cat.
public abstract class BaseModule
{
public string UsedSource { get; set; }
public void Write(string text)
{
OtherStaticClass.Log(UsedSource, text);
}
}
public class ModuleA : BaseModule
{
public ModuleA()
{
UsedSource = "A";
}
}
public class ModuleB : BaseModule
{
public ModuleB()
{
UsedSource = "B";
}
}
To get your output then, you just need to create new instances of ModuleA and ModuleB.
var moduleA = new ModuleA();
var moduleB = new ModuleB();
moduleA.Write("Hi");
moduleB.Write("Hi");
Using a static class means using a singleton. Singletons defeat the purpose of tracking the effective dependencies of your classes.
Anyway, you can approach the problem by refactoring your code and using a factory:
In this case, just drop the static keyword and let the class be inheritable (you have to add the appropriate virtual keywords to allow proper inheritance):
public class BaseModule
{
public string UsedSource {get; set;}
public Write(string text)
{
OtherStaticClass.Log(UsedSource, text);
}
}
Then, add an additional class which holds the reference (I gave useless names, focus on the purpose):
public static class MySingleton
{
public static BaseModule _Module;
public static BaseModule Module
{
get
{
return _Module;
}
}
public static void ChangeImplementation (BaseModule module)
{
// do your checks here
_Module = module;
}
}
This way wou can achieve what you ask.
As you can see, this code has several issues, among them it's important to note that this code has global side effects and is not thread safe.
A better approach is to have drop the singleton entirely, and pass the BaseModule class (that can be inherited) as an argument of methods/constructors when needed.
I don't see that you need more than one static class. Instead separate the logic into methods in one static class.
public static class Module
{
private const string SourceA = "A";
private const string SourceB = "B";
public static WriteA(string text)
{
Write(SourceA, text);
}
public static WriteB(string text)
{
Write(SourceB, text);
}
private static Write(string source, string text)
{
OtherStaticClass.Log(source, text);
}
}
Then instead of
ModuleA.Write("Hi");
ModuleB.Write("Hi");
you'd do
Module.WriteA("Hi");
Module.WriteB("Hi");
If you can't change the BaseModule class, you can use it with other state and recover state after using:
public static class BaseModule
{
public static string UsedSource {get; set;}
public static Write(string text)
{
OtherStaticClass.Log(UsedSource, text);
}
}
internal class Writer : IDisposable
{
string _lastSource;
public Writer(string source)
{
_lastSource = BaseModule.UsedSource;
BaseModule.UsedSource = source;
}
public void Dispose()
{
BaseModule.UsedSource = _lastSource;
}
}
internal abstract class Module
{
public abstract Source { get; };
public void Write(string text)
{
using (var writer = new Writer(Source))
{
BaseModule.Write(text);
}
}
}
internal class ModuleA : Module
{
public override Source => "A";
}
internal class ModuleB : Module
{
public override Source => "B";
}
But you must ensure thread safety.
If you can change the BaseModule class:
public static class BaseModule
{
public static Write(string text, string source)
{
OtherStaticClass.Log(source, text);
}
}
internal abstract class Module
{
public abstract Source { get; };
public void Write(string text)
{
BaseModule.Write(text, Source);
}
}
internal class ModuleA : Module
{
public override Source => "A";
}
internal class ModuleB : Module
{
public override Source => "B";
}

Can I create a wrapper that intercept all calls to objects implementing certain interface?

Let's say I have an interface IFoo
interface IFoo
{
int Bar();
int Bar2();
void VBar();
//etc,
}
Can I create a wrapper that takes any IFoo object and do something before/after the actual call?
e.g. when I do something like this
IFoo wrappedFoo = new Wrapper<IFoo>(actualFooObject).Object;
wrappedFoo.Bar();
then the wrapper.Bar() method actually execute something like this
PreCall(); //some code that I can define in the wrapper
actualFooObject.Bar();
PostCall();
Is there a simple and clean way to do this?
You can use Code Contracts for this approach. Take a look on section 2.8 Interface Contracts of user manual (pdf).
You can use AOP. I´ve been using this library for quite some time now:
http://www.postsharp.net/products
if you need to have something on PreCall() and PostCall , the simple way is to wrap under the proxy base approach
public abstract class ProxyBase
{
public void Execute()
{
PreCondition();
Call();
PostCondition();
}
private void PreCondition()
{
Console.WriteLine("ProxyBase.PreCondition()");
}
private void PostCondition()
{
Console.WriteLine("ProxyBase.PreCondition()");
}
protected abstract void Call();
}
public class AppProxy<T> : ProxyBase where T : IApp
{
private IApp _app;
public AppProxy<T> Init(IApp app)
{
_app = app;
return this;
}
protected override void Call()
{
Console.WriteLine("AppProxy.Call()");
_app.Call();
}
public IApp Object
{
get { return _app; }
}
}
public interface IApp
{
void Call();
}
public interface IFoo : IApp
{
}
public class ActualFoo : IApp
{
public void Call()
{
Console.WriteLine("ActualFoo.Call()");
}
}
class Program
{
static void Main(string[] args)
{
ActualFoo actualFoo = new ActualFoo();
var app = new AppProxy<IFoo>().Init(actualFoo);
app.Execute();
var o = app.Object as ActualFoo;
Console.ReadLine();
}
}
--------------- Output --------------
ProxyBase.PreCondition()
AppProxy.Call()
ActualFoo.Call()
ProxyBase.PreCondition()
I don't see a "clean and simple" way of doing this.
The best option I can come up with is writing a generic Wrapper<T> that encapsulates and instance of T and implements generic Precall and Postcall methods:
public class Wrapper<T>
{
protected T _instance;
public Wrapper(T instance)
{
this._instance = instance;
}
protected virtual void Precall()
{
// do something
}
protected virtual void Postcall()
{
// do something
}
}
So that you can write your own FooWrapper for interface IFoo (or any other interface) and just delegate method calls:
public class FooWrapper :Wrapper<IFoo>, IFoo
{
public FooWrapper(IFoo foo)
: base(foo)
{
}
public int Bar()
{
base.Precall(); return base._instance.Bar(); base.Postcall();
}
public int Bar2()
{
base.Precall(); return base._instance.Bar2(); base.Postcall();
}
public void VBar()
{
base.Precall(); base._instance.VBar(); base.Postcall();
}
}
So you can use it like this:
IFoo f = new ActualFooClass();
IFoo wf = new FooWrapper(f);
f.Bar();
Of course, if your Precall and Postcall methods are not generic, then there is really no point in using the Wrapper<T> class. Just go with the FooWrapper.

Is there a way to Create nunit Setup with arguments

Is there a way to add arguments to an nunit setup method like this: public void SetUp(Point p = null) { /*code*/ }.
I tried it and got the following exception SetUp : System.Reflection.TargetParameterCountException : Parameter count mismatch
I think that your point is to avoid code duplication.
Try to extract base class with overriten method used in SetUp().
All derived class will execute tests from base class, with objects prepared in overriten OnSetUp()
[TestFixture]
public class BaseTestsClass
{
//some public/protected fields to be set in SetUp and OnSetUp
[SetUp]
public void SetUp()
{
//basic SetUp method
OnSetUp();
}
public virtual void OnSetUp()
{
}
[Test]
public void SomeTestCase()
{
//...
}
[Test]
public void SomeOtherTestCase()
{
//...
}
}
[TestFixture]
public class TestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
[TestFixture]
public class OtherTestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
Using parametrised TestFixture also can be usefull. Tests in class will be lunched per TestFixture, SetUp method also.
But remember that
Parameterized fixtures are (as you have discovered) limited by the fact that you can only use arguments that are permitted in attributes
Usage:
[TestFixture("some param", 123)]
[TestFixture("another param", 456)]
public class SomeTestsClass
{
private readonly string _firstParam;
private readonly int _secondParam;
public WhenNoFunctionCodeExpected(string firstParam, int secondParam)
{
_firstParam = firstParam;
_secondParam = secondParam;
}
[Test]
public void SomeTestCase()
{
...
}
}

Wrapping methods with different signatures, pre-and-post-invocation

How to avoid a pair of repetitive lines before and after invocations in sample below ?
Details: This is compileable mock of what is real larger code. Generally it is a layer of proxy classes containing service clients with variety of APIs. The repetitive part is pre- and post- invocation for every method of every client. Unfortunately there is no single signature for all possible methods, the pre- and post- parts need a pointer to client's channel and context.
Is it possible to apply something advanced like AOP, Generics, Delegates, Attributes etc. ? Thank you
using System;
namespace ConsoleApplication
{
class ClassServiceClient: IDisposable
{
public Object channel()
{
return "something";
}
public Object context()
{
return "something other";
}
}
class ClassA : ClassServiceClient
{
public Object methodA()
{
return "something other";
}
}
class ClassB : ClassServiceClient
{
public void methodB(string param)
{
return;
}
}
class ClassAProxy
{
public Object methodA()
{
using (ClassA client = new ClassA())
{
Program.preparation(client.channel()); //<---- repetitive part
Object result = client.methodA();
Program.postinvocation(client.context());//<---- repetitive part
return result;
}
}
}
class ClassBProxy
{
public void methodB(string param)
{
using (ClassB client = new ClassB())
{
Program.preparation(client.channel()); //<---- repetitive part
client.methodB(param);
Program.postinvocation(client.context());//<---- repetitive part
return;
}
}
}
class Program
{
public static void preparation(Object channel)
{
// Do something with channel
}
public static void postinvocation(Object context)
{
// Do something with context
}
static void Main(string[] args)
{
}
}
}
If you can use a common base class, you can easily use a public sealed method that does the invocation and a protected abstract method that does the logic, e.g.
class ProxyBase{
public void Method(params object[] args){
PreConditions();
Invoke(args);
PostConditions();
}
protected abstract void Invoke(object[] args);
}
class ClassAProxy{
protected override void Invoke(object[] args){
client.Method(args[0]);
}
}
You can achieve similar results functionally by declaring a InvocationHandler in your Program class that takes an action:
class Program{
public static void Invoke(object[] args, Action action){
PreConditions();
action();
PostConditions();
}
}
class ClassAProxy{
public void MethodA(int i){
Program.Invoke(() => client.Something(i));
}
}

Constructor Inject with Ninject 2

I've used Ninject with MVC3 for automagic inject of constructor arguments. It worked great.
How do you do something similar with non-MVC code.
For example:
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
public void Strike()
{
_weapon.Strike();
}
}
public class MyProgram
{
public void DoStuff()
{
var Ninja = new Ninja(); // I'm wanting Ninject to call the parameterized Ninja constructor
ninja.Strike();
}
}
How would I alter the code to get it to work?
public interface IWeapon
{
void Strike();
}
public class Sword : IWeapon
{
public void Strike()
{
Console.WriteLine("black ninja strike");
}
}
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
public void Strike()
{
_weapon.Strike();
}
}
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
}
}
class Program
{
static void Main()
{
var kernel = new StandardKernel(new WarriorModule());
var ninja = kernel.Get<Ninja>();
ninja.Strike();
}
}
Wouldn't it just be:
var ninja = Kernel.Get<Ninja>();
You obviously have to resolve the dependency though Ninject.
You need to have an instance of StandardKernel let's call it kernel and then use kernel.Get<Ninja>(). This works since Ninja is non abstract, so it is considered bound to itself. Obviously some concrete types needs to be bound to IWeapon to allow NInject to create Ninja.

Categories