How to call static method of static generic class with C# Reflection? - c#

I have many classes with these implementations:
internal static class WindowsServiceConfiguration<T, Y> where T : WindowsServiceJobContainer<Y>, new() where Y : IJob, new()
{
internal static void Create()
{
}
}
public class WindowsServiceJobContainer<T> : IWindowsService where T : IJob, new()
{
private T Job { get; } = new T();
private IJobExecutionContext ExecutionContext { get; }
public void Start()
{
}
public void Install()
{
}
public void Pause()
{
}
public void Resume()
{
}
public void Stop()
{
}
public void UnInstall()
{
}
}
public interface IWindowsService
{
void Start();
void Stop();
void Install();
void UnInstall();
void Pause();
void Resume();
}
public class SyncMarketCommisionsJob : IJob
{
public void Execute(IJobExecutionContext context)
{
}
}
public interface IJob
{
void Execute(IJobExecutionContext context);
}
I would like to call Create() method of WindowsServiceConfiguration static class by reflection as below:
WindowsServiceConfiguration<WindowsServiceJobContainer<SyncMarketCommisionsJob>, SyncMarketCommisionsJob>.Create();
and I don't know how to do that by using Activator or something like that in order to call Create method in my C# code?
best regards.

Something like this ought to work:
// Get the type info for the open type
Type openGeneric = typeof(WindowsServiceConfiguration<,>);
// Make a type for a specific value of T
Type closedGeneric = openGeneric.MakeGenericType(typeof(WindowsServiceJobContainer<SyncMarketCommisionsJob>), typeof(SyncMarketCommisionsJob));
// Find the desired method
MethodInfo method = closedGeneric.GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod);
// Invoke the static method
method.Invoke(null, new object[0]);

Related

How to implement a non-generic interface and call with generic

Probably a bad title, but I am trying to abstract away the type "EventHub" from my generic Handler class.
I would like to inject a function instead into my subscribe method to decouple the two types. Unfortunately, the only way I can see doing this is if I make my IHandler a generic, but this causes other problems.
Is there a design pattern to decouple these two types? Commented out are lines that I would like in some way.
public interface IHandler
{
//void Subscribe(Func<Action<T>, Guid> subscribe);
void Subscribe(EventHub eventHub);
void Unsubscribe(Action<Guid> action);
}
public abstract class Handler<T> : IHandler
{
private Guid _subscriptionToken;
public virtual void Subscribe(EventHub eventHub)
{
var action = new Action<T>(Handle);
_subscriptionToken = eventHub.Subscribe(action);
}
/*public virtual void Subscribe(Func<Action<T>, Guid> subscribe)
{
var action = new Action<T>(Handle);
_subscriptionToken = subscribe(action);
}*/
public virtual void Unsubscribe(Action<Guid> action)
{
action(_subscriptionToken);
}
public abstract void Handle(T eventType);
}
Thanks for the help!
internal interface IHandler
{
void Subscribe(Func<Action<object>, Guid> subscribe);
void Unsubscribe(Action<Guid> action);
}
public abstract class Handler<T> : IHandler
{
private Guid _subscriptionToken;
public virtual void Subscribe(Func<Action<object>, Guid> subscribe)
{
var action = new Action<T>(HandleNonAsync);
_subscriptionToken = subscribe(Convert(action));
}
public virtual void Unsubscribe(Action<Guid> action)
{
action(_subscriptionToken);
}
public abstract Task HandleAsync(T eventType);
private void HandleNonAsync(T eventType)
{
HandleAsync(eventType).GetAwaiter().GetResult();
}
private Action<object> Convert(Action<T> myActionT)
{
if (myActionT == null) return null;
else return new Action<object>(o => myActionT((T)o));
}
}

How to invoke unit test class in reflection c#

I have a class which is decorated with [TestFixture] attribute and this class contains methods that are decorated with [Test] attribute, each method signature is
public void MethodName([ValueSource("TestConfigurations")] TestConfiguration tConf)
also there are set up and tear down methods
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
}
[SetUp]
public void TestSetUp() { }
[TearDown]
public void TestTearDown()
{
}
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
}
how can I run this unit test class via reflection in c#?
Thank you in advanced
Something like:
public static class RunUnitTestsClass<TUnitTests> where TUnitTests : new()
{
private static IEnumerable<MethodInfo> WithAttribute<TAttribute>()
{
return typeof(TUnitTests).GetMethods().Where(method => method.GetCustomAttributes(typeof(TAttribute), true).Any());
}
private static void RunWithAttribute<TAttribute>()
{
var unitTests = new TUnitTests();
foreach (var method in WithAttribute<TAttribute>())
method.Invoke(unitTests, new object[0]);
}
public static void RunTestFixtureSetup()
{
RunWithAttribute<TestFixtureSetUp>();
}
// same for the rest of them
public static void RunTests(TestConfiguration tConf)
{
var unitTests = new TUnitTests();
foreach (var method in WithAttribute<Test>())
method.Invoke(unitTests, new []{tConf});
}
}

implementing delegate in interface

I can't find a way to implement delegate in interface
I want to get this:
public class SomeClass : ISomeInterface
{
public delegate void SomeCallback();
public SomeCallback callback;
public void SomeMethod()
{
callback.invoke();
}
}
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
SomeClass s = new SomeClass();
s.callback = Callback;
s.SomeMethod();
}
}
but in case when I create instance of the class "SomeClass" using interface:
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
ISomeInterface s = new SomeClass(); // <<<----
s.callback = Callback; // here will be an error :(
s.SomeMethod();
}
}
Please, help me with it :)
Moving the callback to the interface is required if you want to use the callback without casing to a concrete type. Note that your current implementation has callback as a field. To declare it in an interface, you must make it a property.
Because properties are really methods, you must implement the property in your concrete class. Using an auto-property is fine for the implementation here.
Once you've made those changes, you can then set and call the callback using only the interface.
public delegate void SomeCallback();
public interface ISomeInterface {
SomeCallback callback { get; set; }
void SomeMethod();
}
public class SomeClass : ISomeInterface
{
public SomeCallback callback { get; set; }
public void SomeMethod()
{
callback.Invoke();
}
}
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
ISomeInterface s = new SomeClass();
s.callback = Callback;
s.SomeMethod();
}
}

MS unity container

I have an interface IInterface and it looks something like below -
public interface IInterface
{
void SomeMethod1();
void SomeMethod2();
void SomeMethod3();
.
.
.
}
One of the implementations is something like -
public class Implementation : IInterface
{
private Object obj;
public Implementation(Object obj)
{
this.obj = obj;
// Do Something
}
public void SomeMethod1()
{
lock(obj)
{
// Do Something
}
}
public void SomeMethod2()
{
// Do Something
}
public void SomeMethod3()
{
lock(obj)
{
// Do Something
}
}
.
.
.
}
How to pass a static readonly instance of type Object while registering Implementation class with type IInterface via unity configuration?
My preferred approach is probably to create a factory for creating IInterfaces
public interface IInterface
{
void SomeMethod1();
}
public interface IInterfaceFactory
{
IInterface CreateInterface();
}
public class StandardInterfaceFactory : IInterfaceFactory
{
// Define your static lock object here. Other customers
// can define their own IInterfaceFactory to use a
// different lock object.
private static readonly object lockObject = new object();
public IInterface CreateInterface()
{
return new StandardInterface(lockObject);
}
}
public class StandardInterface : IInterface
{
private readonly object lockObject;
public StandardInterface(object lockObject)
{
this.lockObject = lockObject;
}
public void SomeMethod1()
{
lock (this.lockObject)
{
Console.WriteLine("I've locked on " + lockObject);
}
}
}
Your unity configuration and client code will then look like this.
void Main()
{
IUnityContainer container = new UnityContainer();
// This mapping can be done trivially in XML configuration.
// Left as an exercise for the reader :)
container.RegisterType<IInterfaceFactory, StandardInterfaceFactory>();
IInterfaceFactory factory = container.Resolve<IInterfaceFactory>();
IInterface myInterface = factory.CreateInterface();
myInterface.SomeMethod1();
}

Implementing a templated interface

I'm trying to write this more generically:
public static CormantRadDock RecreateDock(RadDockSetting settings)
{
CormantRadDock dock = new CormantRadDock();
settings.SetSettings(dock);
Logger.DebugFormat("Recreated dock {0}", dock.ID);
return dock;
}
I have this:
public static T Recreate<T>() where T : new()
{
T _control = new T();
//settings.SetSettings(dock);
Logger.DebugFormat("Recreated control {0}", (_control as Control).ID);
return _control;
}
Generic Solution:
public interface ISetting<T>
{
void SetSettings(T obj);
}
public void SetSettings(CormantRadDock dock)
{
// do stuff with dock
}
Thanks!
Is this what you're trying to do?
// move the generic type parameter up here so the interface is generic
// and not the method definition
public interface ISetting<T>
{
void SetSettings(T obj);
}
Then you can implement it successfully in a class:
public class SomeClass: ISetting<YourSettingType>
{
public void SetSettings(YourSettingType obj) { ... }
}
either
public abstract class ISetting<T>
{
public abstract void SetSettings<T>(T obj);
}
public void SetSettings<T>(T dock)
{
// do stuff with dock
}
or
public abstract class ISetting<T>
{
public abstract void SetSettings(T obj);
}
public void SetSettings(T dock)
{
// do stuff with dock
}
How about this:
public interface ICanBeRecreated<T>
{
T Recreate();
}
public class CormantDock : ICanBeRecreated<CormantDock>
{
private RadDockSetting _settings;
private void ApplySettings(RadDockSetting settings)
{
// apply settings
}
public CormantDock Recreate()
{
var dock = new CormantDock;
dock.ApplySettings(_settings);
}
}

Categories

Resources