How to invoke a method in interface using reflection - c#-4.0

I have a class and that class 'class1' is implementing an interface interface1
I need to invoke a method in the class using the reflection.
I can't use the class name and interface name as it is because both the name will change dynamically.`
interface1 objClass = (interface1 )FacadeAdapterFactory.GetGeneralInstance("Class"+ version);
See the above code snippet. The class name and the interface name should change according to its version. I have created the instance for class by using
Activator.CreateInstance(Type.GetType("Class1"))
but i m not able to crete the same for interface
Is there any way to implement the above context.

You can't create instance of interface, just class that implements interface.
There are some ways to extract method (info) from interface.
ISample element = new Sample();
Type iType1 = typeof(ISample);
Type iType2 = element.GetType().GetInterfaces()
.Single(e => e.Name == "ISample");
Type iType3 = Assembly.GetExecutingAssembly().GetTypes()
.Single(e => e.Name == "ISample" && e.IsInterface == true);
MethodInfo method1 = iType1.GetMethod("SampleMethod");
MethodInfo method2 = iType2.GetMethod("SampleMethod");
MethodInfo method3 = iType3.GetMethod("SampleMethod");
method1.Invoke(element, null);
method2.Invoke(element, null);
method3.Invoke(element, null);
I hope it's sufficient.

Related

Get instance of class dynamically in .NetCore

I need class instance from string to check if it has certain Attribute.
I have tried it like this
Type type = Assembly.GetEntryAssembly().GetType("ClassName");
object entity = Activator.CreateInstance(type);
var tableAttribute = entity.GetType().GetTypeInfo().GetCustomAttribute<TableAttribute>();
but type is null ?
Entire code in TestConsoleApp:
using System;
using System.ComponentModel;
using System.Reflection;
namespace AssemblyTest
{
[Description("TestDescription")]
public class TestClass { }
//
public class Program
{
public static void Main(string[] args)
{
Type type = Assembly.GetEntryAssembly().GetType("TestClass");
if(type == null)
Console.WriteLine("Object type is NULL.");
else
Console.WriteLine("Object type has value.");
object entity = Activator.CreateInstance(type);
var tableAttribute = entity.GetType().GetTypeInfo().GetCustomAttribute<DescriptionAttribute>();
}
}
}
When specifying the name of the class you must provide a fully qualified name that includes it's namespace. So this line needs tweaked:
Type type = Assembly.GetEntryAssembly().GetType("ClassName");
If ClassName is in namespace App.Logic then the line should be:
Type type = Assembly.GetEntryAssembly().GetType("App.Logic.ClassName");
So given your updated code the line should be:
Type type = Assembly.GetEntryAssembly().GetType("AssemblyTest.TestClass");
I have tested it and it does work if a fully qualified class name is used which includes the namespace information.

initializing derived class member variables using base class reference object

I came across a lot of code in our company codebase with the following structure
class Base
{
public Base (var a, var b)
{
base_a = a;
base_b = b;
}
var base_a;
var base_b;
}
class Derived:Base
{
publc Derived (var a,b,c,d): base (a,d)
{
der_c = c;
der_d = d;
}
var der_c;
var der_d;
var der_e;
}
class Ref
{
Base _ref;
public Ref( var a,b,c,d)
{
_ref = new Derived (a,b,c,d)
}
public void method( )
{
_ref.der_e = 444; // won't compile
}
}
What is the correct way to initialize der_e ? What is the advantages of having a reference of base class and using an object derived class for _ref ? Just the fact that using a base class reference can hold multiple derived class objects ? If that's the case, should all the member variables of derived class be initialized during construction itself (like this: _ref = new Derived (a,b,c,d) ). What if I want to initialize _ref.der_e later in a method ? I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e = 444) but this look doesn't seem to the best practice. What is the idea of having such a structure and what is the correct of initializing a member of a derived class object after it has been constructed ?
Those are too many questions in a single post.
What is the correct way to initialize der_e ?
For initializing der_e you will have to have Reference of Derived class as it knows about the der_e property and not Base class.
What is the advantages of having a reference of base class and using
an object derived class for _ref ?
Yes that's called Polymorphism which is the essence of Object Oriented Programming. It allows us to hold various concrete implementations without knowing about the actual implementation.
If that's the case, should all the member variables of derived class
be initialized during construction itself (like this: _ref = new
Derived (a,b,c,d) )
There is no such rule. It depends on your scenario. If the values are not meant to be changed after the creation of the object and the values are known before hand during construction of the object then they should be initialized during construction.
Again if there are various scenarios like sometimes values are known and sometimes not then there can be Overloaded Constructors, which take different arguments.
What if I want to initialize _ref.der_e later in a method ?
That is perfectly fine, it depends on what you are trying to achieve. The question is not a concrete one but an abstract one in which it is difficult to comment on what you are trying to achieve.
I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e =
444) but this look doesn't seem to the best practice.
I am sharing some Java code which is similar to C# as I am from Java background
//This class knows about Base and nothing about the Derived class
class UserOfBase{
Base ref;
//Constructor of UserOfBase gets passed an instance of Base
public UserOfBase(Base bInstance){
this.ref = bInstance;
}
//Now this class should not cast it into Derived class as that would not be a polymorphic behavior. In that case you have got your design wrong.
public void someMethod(){
Derived derivedRef = (Derived)ref; //This should not happen here
}
}
I am sharing some references which would help you with this, as I think the answer can be very long to explain.
Factory Pattern
Dependency Injection
Head First Design Patterns
Posts on SO regarding polymorphism
You can create a constructor in your derived class and map the objects or create an extension method like this:
public static class Extensions
{
public static void FillPropertiesFromBaseClass<T1, T2>(this T2 drivedClass, T1 baseClass) where T2 : T1
{
//Get the list of properties available in base class
System.Reflection.PropertyInfo[] properties = typeof(T1).GetProperties();
properties.ToList().ForEach(property =>
{
//Check whether that property is present in derived class
System.Reflection.PropertyInfo isPresent = drivedClass.GetType().GetProperty(property.Name);
if (isPresent != null && property.CanWrite)
{
//If present get the value and map it
object value = baseClass.GetType().GetProperty(property.Name).GetValue(baseClass, null);
drivedClass.GetType().GetProperty(property.Name).SetValue(drivedClass, value, null);
}
});
}
}
for example when you have to class like this:
public class Fruit {
public float Sugar { get; set; }
public int Size { get; set; }
}
public class Apple : Fruit {
public int NumberOfWorms { get; set; }
}
you can initialize derived class by this code:
//constructor
public Apple(Fruit fruit)
{
this.FillPropertiesFromBaseClass(fruit);
}

How to convert NSDictionary() with values [PSPDFAnnotationParser class] / [MyCustomAnnotationParser class] into MonoTouch?

From the documentation of a bound API I'm using:
overrideClassNames
Use this to use specific subclasses instead of the default PSPDF*
classes. e.g. add an entry of [PSPDFAnnotationParser class] /
[MyCustomAnnotationParser class] as key/value pair to use the custom
subclass. (MyCustomAnnotationParser must be a subclass of
PSPDFAnnotationParser) Throws an exception if the overriding class is
not a subclass of the overridden class. Note: does not get serialized
when saved to disk.
#property (nonatomic, strong) NSDictionary *overrideClassNames
Here's what I tried but doesn't work. Appearently not strings are required but actual types or something. How can I use this in MonoTouch?
var oClassDic = new NSMutableDictionary();
oClassDic.Add(new NSString("[PSPDFAnnotationParser class]"), new NSString("[PSPDFKitAnnotationParser class]"));
oDoc.OverrideClassNames = oClassDic;
The PSPDFKitAnnotationParser I created like this:
[Register("PSPDFKitAnnotationParser")]
public class PSPDFKitAnnotationParser : PSPDFAnnotationParser
{
public PSPDFKitAnnotationParser () : base()
{
}
public PSPDFKitAnnotationParser (PSPDFDocumentProvider provider) : base(provider)
{
}
public PSPDFKitAnnotationParser (IntPtr handle) : base(handle)
{
}
public PSPDFKitAnnotationParser (NSObjectFlag t) : base(t)
{
}
public PSPDFKitAnnotationParser (NSCoder coder) : base(coder)
{
}
MonoTouch's own bindings generally hides the class and replace them with, the more .NETy, System.Type.
However the MonoTouch.ObjCRuntime.Class type exists and can also be used. If the native code expects class instances then you should be able to do something like:
var oClassDic = new NSMutableDictionary();
oClassDic.Add(new Class("PSPDFAnnotationParser"), new Class("PSPDFKitAnnotationParser"));
oDoc.OverrideClassNames = oClassDic;
You might have to tweak this a bit since a Class instance is not an NSObject, it's a NativeObject in MonoTouch, so you might have to go one level deeper and use the Handle properties (IntPtr) when adding values/keys to your dictionary.
Following #poupou answer this might work, I have not tested it this is what you have to do, It Works (TM)
var oClassDic = new NSMutableDictionary();
var key = new Class("PSPDFAnnotationParser");
var val = new Class("PSPDFKitAnnotationParser");
IntPtr selSetObjectForKey = Selector.GetHandle ("setObject:forKey:");
Messaging.void_objc_msgSend_IntPtr_IntPtr (oClassDic.Handle, selSetObjectForKey, val.Handle, key.Handle);
oDoc.OverrideClassNames = oClassDic;
Selector setObject: forKey: expects an ObjC id type on both params
"id" its just a special type that can hold a pointer to any object you can construct with ObjC
So this should work :)
Hope this helps
Alex

c# how to convert code into a generic version?

I am trying to write this code in a more generic fashion:Is it possible that based on T i can use the right entityframework entity? So for example if I would use :
public IQueryable<T> GetCount(string filterExpression)
{
//return db.Persons.Where("it." + filterExpression);
return db. ? .Where("it." + filterExpression); // depending on type T
}
UPDATE
so now I did this:
public int GetCount<T>(string filter)
where T : class
{
NortwindEntities db = new NortwindEntities();
return db.CreateObjectSet<T>().Where(filter).Count();
}
error:
Error 2 The constraints for type parameter 'T' of method 'MyBase<T>.GetCount<T>(string)' must match the constraints for type parameter 'T' of interface method 'MyBase<T>.GetCount<T>(string)'. Consider using an explicit interface implementation instead
Are you sure that you want a queryable of T? (the name of your method is GetCount.)
You can do this to get a IQueryable<T> from your DbContext.
public IQueryable<T> GetCount<T>(Func<T, bool> predicate)
where T : class
{
MyContext db = new MyContext();
return db.Set<T>().Where(predicate).AsQueryable();
}
IQueryable<Person> result = GetCount<Person>(x => x.Id == 1);
I suggest to use the name Where as your method name.
public IQueryable<T> Where<T>(Func<T, bool> predicate)
where T : class
{
MyContext db = new MyContext();
return db.Set<T>().Where(predicate).AsQueryable();
}
IQueryable<Person> result = Where<Person>(x => x.Id == 1);
Update
Decorate the method with where T : class if you get the following exception.
The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method ?
Update 2
Seems that you really only want the count.
public int GetCount<T>(Func<T, bool> predicate)
where T : class
{
MyContext db = new MyContext();
return db.Set<T>().Where(predicate).Count();
}
int count = GetCount<Person>(x => x.Id == 1);

Using reflection how to find a class in an assembly which implements a generic base class and create its instance

I've a base presenter class:
public abstract class PresenterBase<T> where T : IView
{
//Some code
}
A concrete presenter class that implements this base:
public class RegistrationPresenter : PresenterBase<IRegistration>
{
//Some Code
}
A concrete presenter factory to return the instance of presenter which depends on a specific interface contract:
public class ProductPresenterFactory : PresenterFactoryBase
{
// Some code
public override PresenterBase<IView> GetPresenter(IView view, string name = "")
{
if (view == null && string.IsNullOrEmpty(name))
throw new ArgumentNullException();
return presenter;
}
}
I need to implement the GetPresenter method. The user will put the interface contract, for example of type IRegistration in the above case. This method should figure out the class that implements PresenterBase<IRegistration> and return an instance.
I did not write this with a compiler; I might have made a few mistakes.
You'll first need to get the type of the presenterbase, then we'll scour the assemble for the implementation, then call it's constructor. I'll make some assumptions as written in the code.
var genericType = typeof (PresenterBase<>).MakeGenericType(new[] { view.GetType() });
var allTypes = GetType().Assembly.GetTypes(); // I assume the class is in the same assembly.
var typeToImplement = allTypes.Single(t => t.IsSubclassOf(genericType)); // I assume there is only one implementation for the given type
var constructorToCall = typeToImplement.GetConstructors().First(); // I assume there is one constructor
var presenter = constructorToCall.Invoke(new object[0]); // I assume there is no parameter

Resources