.NET Remoting with Reflection - c#

I need to dynamically load an interface assembly that I use on client-side remoting. Something like this.
static void Main(string[] args)
{
TcpClientChannel clientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(clientChannel, false);
Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
Type iTheInterface =
interfaceAssembly.GetType("RemotingInterface.ITheService");
RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
object wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
}
Only I can't seem to grasp how to call any methods as I can't cast the Activator.GetObject. How can I create a proxy of ITheService without knowing the interface at compile-time?

Got an answer from MSDN forums.
static void Main(string[] args)
{
TcpClientChannel clientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(clientChannel, false);
Assembly interfaceAssembly = Assembly.LoadFile("RemotingInterface.dll");
Type iTheInterface = interfaceAssembly.GetType("RemotingInterface.ITheService");
RemotingConfiguration.RegisterWellKnownClientType(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
object wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
MethodInfo m = iTheInterface.GetMethod("MethodName");
m.Invoke(wellKnownObject, new object[] { "Argument"});
}

The returned object implements the interface, so you can use reflection to get its member methods and invoke them.
Or, in C#4, you can use dynamic:
dynamic wellKnownObject = Activator.GetObject(iTheInterface,
"tcp://localhost:9090/Remotable.rem");
wellKnownObject.SomeMethod(etc ..);

First, inspect the available methods/interfaces of your object:
object wellKnownObject =
Activator.GetObject(iTheInterface, "tcp://localhost:9090/Remotable.rem");
var objType = wellKnownObject.GetType();
var methods = objType.GetMethods();
var interfaces = objType.GetInterfaces();
After you're sure about the method you want to invoke,
Consider using DLR and/or wrap the dynamic object in a DynamicObject container.
Use methods[i].Invoke on the object.
Here are some examples:
namespace ConsoleApplication1
{
using System;
class Program
{
static void Main()
{
//Using reflection:
object obj = GetUnknownObject();
var objType = obj.GetType();
var knownInterface = objType.GetInterface("IA");
var method = knownInterface.GetMethod("Print");
method.Invoke(obj, new object[] { "Using reflection" });
//Using DRL
dynamic dObj = GetUnknownObject();
dObj.Print("Using DLR");
//Using a wrapper, so you the dirty dynamic code stays outside
Marshal marshal = new Marshal(GetUnknownObject());
marshal.Print("Using a wrapper");
}
static object GetUnknownObject()
{
return new A();
}
} //class Program
class Marshal
{
readonly dynamic unknownObject;
public Marshal(object unknownObject)
{
this.unknownObject = unknownObject;
}
public void Print(string text)
{
unknownObject.Print(text);
}
}
#region Unknown Types
interface IA
{
void Print(string text);
}
class A : IA
{
public void Print(string text)
{
Console.WriteLine(text);
Console.ReadKey();
}
}
#endregion Unknown Types
}

Can I get the Interface information from the remoting URL like http://localhost:8080/xxx.rem?wsdl.
As WebService, I can get the interface information from the service url, http://xXX.xx.xxx.xx/url.svc?wsdl, and compile the assembly by myself code, and invoke methods via reflection.

Related

Cannot cast list of internal class from another assembly in C#

I'm using a function from an external assembly that returns an object which is a list of an internal class and I cannot find a way to cast it in my code.
Code in the external assembly:
namespace AssemblyNamespace
{
internal class InternalClass
{
protected internal byte b;
protected internal int i;
}
public class PublicClass
{
public object PublicMethod()
{
return new List<InternalClass>();
}
}
}
My code:
using AssemblyNamespace;
static void Main()
{
PublicClass P = new PublicClass();
object obj = new object();
obj = P.PublicMethod();
// Is it possible to cast obj?
}
Is it possible to cast obj through reflection or something else? I took a look at question C# - How to access internal class from external assembly but could not find a way to use their suggestions.
You should not expose an internal type from a public API...and you are returning an empty list from PublicMethod() so there is no InternalClass object to access.
But if the PublicMethod() actually returns an InternalClass object...:
public class PublicClass
{
public object PublicMethod()
{
return new List<InternalClass>() { new InternalClass() { b = 10 } };
}
}
...you could access its fields through reflection like this:
static void Main()
{
PublicClass P = new PublicClass();
System.Collections.IList list = P.PublicMethod() as System.Collections.IList;
object internalObject = list[0];
FieldInfo fi = internalObject.GetType().GetField("b", BindingFlags.NonPublic | BindingFlags.Instance);
byte b = (byte)fi.GetValue(internalObject);
Console.WriteLine(b);
}
The above sample code will print "10", i.e. the value of the byte "b" field of the InternalClass object returned from the PublicMethod(), to the Console.

When creating types at runtime, is it possible to use lambdas?

I am trying to create a class and method at runtime, that should implement a given interface. I am using Castle.DynamicProxy nuget package for this purpose.
This is my code:
class Program
{
static void Main(string[] args)
{
var proxymaker = new ProxyMaker<IService>();
var service = proxymaker.Create();
var value = service.GetValue();
}
}
public interface IService
{
int GetValue();
}
public class ProxyMaker<T> where T : class
{
public T Create()
{
var classEmitter = new ClassEmitter(
new ModuleScope(),
"ServiceProxy",
null,
new[] {typeof (T)});
var method = classEmitter.CreateMethod("GetValue", typeof (int));
method.CodeBuilder.AddStatement(new ReturnStatement(new ConstReference(7)));
var type = classEmitter.BuildType();
var instance = Activator.CreateInstance(type);
return (T)instance;
}
}
As you can see, while creating a method, I am just returning a constant int of 7. I want to add a method body there with logic, but the api is not so friendly. Is there any way I can pass a delegate/anonymous method/ lambda expression to it, which will be used as method body ?

Combine multiple interfaces into one at runtime in C#

I need to combine multiple interfaces a runtime to create a new type. For example I might have the following interfaces:
public interface IA{
}
public interface IB{
}
At runtime I want to be able to generate another interface so that in the following sudo code works:
Type newInterface = generator.Combine(typeof(IA), typeof(IB));
var instance = generator.CreateInstance(newInterface);
Assert.IsTrue(instance is IA);
Assert.IsTrue(instance is IB);
Is there a way to do this in .Net C#?
It is possible because of power of Castle Dynamic Proxy
public interface A
{
void DoA();
}
public interface B
{
void DoB();
}
public class IInterceptorX : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(invocation.Method.Name + " is beign invoked");
}
}
class Program
{
static void Main(string[] args)
{
var generator = new ProxyGenerator();
dynamic newObject = generator.CreateInterfaceProxyWithoutTarget(typeof(A), new Type[] { typeof(B) }, new IInterceptorX());
Console.WriteLine(newObject is A); // True
Console.WriteLine(newObject is B); // True
newObject.DoA(); // DoA is being invoked
}
}

Strongly typed way of storing type references

I need to store a collection of types.
All types implement the same interface IHandler<T>, where T is a parameter of the parent class.
At runtime, I enumerate the list of handlers and process a message. Each handler is created by a builder (just uses StructureMap internally). The builder exposes a method like:
static void DoSomething<T>(Action<T> action)
{
}
Of course, I only have a Type so can't use the above.
I've got round this by also passing the underlying interface as the generic parameter and the concrete type as a parameter:
DoSomething<IHandler<T>>(handlerType, h =>
{
h.Handle(message);
});
Then inside DoSomething I can get an instance of handlerType but cast it as IHandler<T>.
Just wondered if there was a better/cleaner way.
Update
In response to some of the comments.
The collection is an ICollection<Type>, not instances. The message handlers are created on demand, on different threads, for each batch of messages, so creating the handlers in advance, or using Lazy<T>, was not an option.
Essentially I am trying to abstract away some direct references to StructureMap. Specifically, DoSomething<T> actually creates the handler using a nested container, before executing the action (it's Handle method).
Update 2 (solution)
I realized that I could handle (no pun intended) this better by storing a collection of Action<T> and creating the handlers using a factory. Here's a simple example:
public class SimpleProcessor<T> where T : IMessage
{
ICollection<Action<T>> handlers;
T message;
public SimpleProcessor(T message)
{
this.handlers = new List<Action<T>>();
this.message = message;
}
public void AddHandler(Action<T> handler)
{
handlers.Add(handler);
}
public void Process()
{
foreach (var handler in handlers)
{
handler(message);
}
}
}
Usage:
var testMessage = new TestMessage { Message = "Foo" };
var simpleProcessor = new SimpleProcessor<TestMessage>(testMessage);
simpleProcessor.AddHandler(m => DoSomething<TestMessageHandler>(h => h.Handle(m)));
simpleProcessor.Process();
I'm more or less happy with this solution.
If you're willing to change Action<T> into Action<dynamic>, then you can do something like this:
class Program
{
static void Main(string[] args)
{
try
{
var myMessage = new object();
Action<dynamic> action = (dynamic h) => { h.Handle(myMessage); };
Type myType = typeof(int);
var method = typeof(Program).GetMethod("DoSomething");
var concreteMethod = method.MakeGenericMethod(myType);
concreteMethod.Invoke(null, new [] { action });
Console.ReadKey();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
Console.ReadKey();
}
}
static public void DoSomething<T>(Action<dynamic> action)
{
Console.WriteLine("DoSomething invoked with T = " + typeof(T).FullName);
}
}

MEF: GetExportedValue from Type?

Using MEF I can create and load a type like this:
var view = Container.GetExportedValue<MyView>();
Now what I want to do is this:
Type t = typeof(MyView);
var view = Container.GetExportedValue<t>();
(of course the type might contain something different than MyView).
This is not possible using the generics GetExportedValue<> - is there some other way to achieve this?
You can use reflection.
Here is an example:
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
namespace WindowsFormsApplication1
{
static class Program
{
[STAThread]
static void Main()
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(IMessage).Assembly));
CompositionContainer container = new CompositionContainer(catalog);
Type t = typeof(IMessage);
var m = container.GetExportedValue(t);
}
}
public static class CompositionContainerExtension
{
public static object GetExportedValue(this ExportProvider container, Type type)
{
// get a reference to the GetExportedValue<T> method
MethodInfo methodInfo = container.GetType().GetMethods()
.Where(d => d.Name == "GetExportedValue"
&& d.GetParameters().Length == 0).First();
// create an array of the generic types that the GetExportedValue<T> method expects
Type[] genericTypeArray = new Type[] { type };
// add the generic types to the method
methodInfo = methodInfo.MakeGenericMethod(genericTypeArray);
// invoke GetExportedValue<type>()
return methodInfo.Invoke(container, null);
}
}
public interface IMessage
{
string Message { get; }
}
[Export(typeof(IMessage))]
public class MyMessage : IMessage
{
public string Message
{
get { return "test"; }
}
}
}

Categories

Resources