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
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.
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 ?
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
}
}
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);
}
}
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"; }
}
}
}