I defined the function in C# DLL as follows,
public class Class1
{
public static dynamic CS_Func()
{
dynamic obj = new ExpandoObject();
obj.num = 99;
return obj;
}
}
In another C# EXE, it could be called like this:
public void CS_Caller()
{
dynamic obj = Class1.CS_Func();
int num = obj.num; // OK
}
But if using C++/CLI, how should I call the CS_Func()?
void CPP_Caller()
{
ExpandoObject ^obj = (ExpandoObject ^)Class1::CS_Func();
//int num = obj->num; // ERROR
}
It solved. Although C++/CLI does not have the keyword of dynamic, it can use ExpandoObject class, which belongs to .NET platform. And ExpandoObject implements the IEnumerable interface, which allows us to enumerate all properties of ExpandoObject.
using namespace System;
using namespace System::Dynamic;
using namespace System::Collections::Generic; // NOT System::Collections
void Cpp_Caller()
{
ExpandoObject ^obj = (ExpandoObject ^)Class1::CS_Func();
for each (KeyValuePair<String^, Object^> ^prop in obj)
{
String ^propname = prop->Key;
Object ^propvalue = prop->Value;
if (propname == "num")
{
int num = (int)propvalue;
}
}
}
Related
I am using JavaAssist to read class information. It is a good and very useful tool.
However, what I have noticed is that it does enumerate or returns the private methods of the class.
Is there a way I can retrieve private methods?
You can use CtClass.getDeclaredMethods( ) to get the information about private methods.
Or as suggested above reflection works fine.
Try giving this a read to know more about the features of javassist.
In order to get all the methods, which also contains the private methods of a a class you could use reflection:
import java.lang.reflect.*;
public class ExampleClass {
public static void main(String[] args) {
ExampleClass cls = new ExampleClass ();
Class c = cls.getClass();
// returns the array of Method objects
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i++) {
System.out.println("method found = " + m[i].toString());
}
}
public ExampleClass () {
// no argument constructor
}
public void publicMethod(String string1) {
// NOPE
}
private void privateMethod(Integer i) {
// NOPE
}
}
Do you know how to add the same module twice to a catalog with different parameters?
ITest acc1 = new smalltest("a", 0)
ITest acc2 = new smalltest("b", 1)
AggregateCatalog.Catalogs.Add(??)
AggregateCatalog.Catalogs.Add(??)
Thanks in advance!
As MEF is limited to its usage of attributes and can be configured by using the Import and Export attributes unlike the flexibility usually provided by IoC Containers, just how one may extend a Part in MEF, one may extend it from a referenced DLL, you could also do something similar where a class inherits from a previous MEF Part by creating a class which exposes some properties with the [ExportAttribute]. The attribute is not limited to the usage on a class, but can be applied to properties. For example, how about something like this.
public class PartsToExport
{
[Export(typeof(ITest))]
public Implementation A
{
get { return new Implementation("A", 5); }
}
[Export(typeof(ITest))]
public Implementation B
{
get { return new Implementation("B", 10); }
}
}
public interface ITest
{
void WhoAmI(Action<string, int> action);
}
[Export]
public class Implementation : ITest
{
private string _method;
private readonly int _value;
public Implementation(string method, int value)
{
_method = method;
_value = value;
}
public void WhoAmI(Action<string, int> action)
{
action(_method, _value);
}
}
[TestClass]
public class Tests
{
[TestMethod]
public void Test()
{
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
CompositionContainer container = new CompositionContainer(catalog);
var tests = container.GetExportedValues<ITest>();
foreach (var test in tests)
{
test.WhoAmI((s, i) => Console.WriteLine("I am {0} with a value of {1}.", s, i));
}
}
}
This outputs the following to the console:
I am A with a value of 5.
I am B with a value of 10.
I have two projects in a solution:
Project A have defined some classes.
Project B is a WCF project and return object from project A
In project A, I write a function to get a list of objects (Song)
public class SongRepository
{
private dbContext db = new dbContext();
public List<Song> getAll()
{
List<Song> songs = db.Songs.ToList();
return songs;
}
}
An in project B, I write a function that used SongRepository to get a list of objects (Song)
public class Service1 : IService1
{
private SongRepository sr = new SongRepository();
public List<Song> getAllSong()
{
List<Song> songs = sr.getAll();
return songs;
}
}
and IService1 class:
namespace webservice
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
List<Song> getAllSong();
}
}
The result is that the WCF project does not return a list of Songs. But I've tested separately in project A and it returns the true data (a list of Songs)
I don't know how to use WCF to get data from another project in the same solution. Can anyone help me?
My problem have solved! Thank you devdigital for answering me.
The solution is that I use an adapter to convert business object to data transfer object. Other people have the same issue as me can go to this link: http://valueinjecter.codeplex.com/
to download the Omu.ValueInjecter dll.
After adding this dll file above, use this two functions to convert BO to DTO:
public T ConvertObjType<T>(object obj)
{
T instance = Activator.CreateInstance<T>();
if (obj != null)
StaticValueInjecter.InjectFrom((object)instance, new object[1]
{
obj
});
return instance;
}
public List<T> ConvertListObjType<G, T>(List<G> listObj)
{
if (listObj == null || listObj.Count == 0)
return (List<T>)null;
List<T> list = new List<T>();
typeof(T).GetProperties();
listObj[0].GetType().GetProperties();
foreach (G g in listObj)
{
object obj = (object)g;
T instance = Activator.CreateInstance<T>();
StaticValueInjecter.InjectFrom((object)instance, new object[1]
{
obj
});
list.Add(instance);
}
return list;
}
I hope this help you out.
A friend of mine (from work) asked me a question.
Remove the static keyword from the Dictionary Live from the Members class.
Don't use new Members(); to create an instance in Check(...) method.
So with these rules, what you have to do for call Live from other class like:
Members.Live.TryGetValue(signatureFromRequest, out userId);
I have this;
using System;
using System.Collections.Generic;
namespace Webbing.Session
{
public class Members
{
// THAT Dictionary Live was a static... public static Dictionary...
public Dictionary Guid, int> Live = new Dictionary Guid,int>();
}
}
and this:
using System;
using WcfService.Session;
namespace Webbing.BusinessDb
{
public class Signature
{
public static bool Check(Guid signatureFromRequest)
{
bool result = false;
int userId;
Members checker = new Members(); // <--------- don't use this
checker.Live.TryGetValue(signatureFromRequest, out userId);
if (userId != 0)
{
result = true;
}
return result;
}
}
}
He is saying, "there is way to do it.", but I can't find it and I don't believe there actually is. What is your opinion?
UPDATE/ANSWER:
I solved the question with Daniel Hilgarth 's help... Here it is;
using System;
using System.Collections.Generic;
namespace Webbing.Session
{
public class Members
{
// Guid, userId
public Dictionary Guid, int> Live = new Dictionary Guid,int>();
private static readonly Members __instance = new Members();
public static Members Instance
{
get
{
return __instance;
}
}
}
}
Usage: Members.Instance.Live.TryGetValue(signatureFromRequest, out userId);
There is no way with the exact syntax you provided.
One possibility would be a singleton, but it would look like this:
Members.Instance.Live.TryGetValue(signatureFromRequest, out userId);
Note the .Instance part.
See here for several ways to implement a singleton.
As you can see, now the Live property isn't static anymore but the new property Instance is...
I guess it will be best to simply ask your colleague what he meant.
I am trying to use Ninject to implement cascading injection into a class that contains an IList field. It seems that, unless I specifically specify each binding to use in the kernel.Get method, the IList property is always injected with a list of a single default object.
The following VSTest code illustrates the problem. The first test fails because the IList field contains one MyType object with Name=null. The second test passes, but I had to specifically tell Ninject what constructor arguments to use. I am using the latest build from the ninject.web.mvc project for MVC 3.
Does Ninject specifically treat IList different, or is there a better way to handle this? Note that this seems to only be a problem when using an IList. Createing a custom collection object that wraps IList works as expected in the first test.
[TestClass()]
public class NinjectTest
{
[TestMethod()]
public void ListTest_Fails_NameNullAndCountIncorrect()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>();
var actual = target.GetList();
// Fails. Returned value is set to a list of a single object equal to default(MyType)
Assert.AreEqual(2, actual.Count());
// Fails because MyType object is initialized with a null "Name" property
Assert.AreEqual("Fred", actual.First().Name);
}
[TestMethod()]
public void ListTest_Passes_SeemsLikeUnnecessaryConfiguration()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>(new ConstructorArgument("myGenericObject", kernel.Get<IGenericObject<MyType>>(new ConstructorArgument("myList", kernel.Get<IList<MyType>>()))));
var actual = target.GetList();
Assert.AreEqual(2, actual.Count());
Assert.AreEqual("Fred", actual.First().Name);
}
}
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IList<MyType>>().ToConstant(new List<MyType> { new MyType { Name = "Fred" }, new MyType { Name = "Bob" } });
Bind<IGenericObject<MyType>>().To<StubObject<MyType>>();
}
}
public class MyModel
{
private IGenericObject<MyType> myGenericObject;
public MyModel(IGenericObject<MyType> myGenericObject)
{
this.myGenericObject = myGenericObject;
}
public IEnumerable<MyType> GetList()
{
return myGenericObject.GetList();
}
}
public interface IGenericObject<T>
{
IList<T> GetList();
}
public class StubObject<T> : IGenericObject<T>
{
private IList<T> _myList;
public StubObject(IList<T> myList)
{
_myList = myList;
}
public IList<T> GetList()
{
return _myList;
}
}
public class MyType
{
public String Name { get; set; }
}
lists, collections and arrays are handled slightly different. For those types ninject will inject a list or array containing an instance of all bindings for the generic type. In your case the implementation type is a class which is aoutobound by default. So the list will contain one instance of that class. If you add an interface to that class and use this one the list will be empty.