Problem saving an object created dynamically with reflection

37 views
Skip to first unread message

Regis Dubois

unread,
Jun 10, 2011, 6:00:02 AM6/10/11
to Castle Project Users
Hi, I am trying to get the following to work without much success:

This class is read from file and compiled in memory:

using System;
using Castle.ActiveRecord;
using iTradeStorage.ValueObjects;
namespace iTradeStorage.ValueObjects
{
[ActiveRecord]
public class iTradeType1 : ActiveRecordBase
{
[PrimaryKey]
public string Identifier { get; set; }
[Property]
public String Col1 { get; set; }
[Property]
public DateTime Col2 { get; set; }
}
}

A table existe in the db that matches this class. (created using
UpdateSchema())

I then try to save an object, the following way:

Type type = _typeManager.GetType(typeVo); //return the
type iTradeType1
object theObject = Activator.CreateInstance(type);
PropertyInfo[] pis = type.GetProperties();
Dictionary<string, PropertyInfo> propertyInfosPerName =
new Dictionary<string, PropertyInfo>();
foreach (PropertyInfo propertyInfo in pis)
{
//PropertyAttributes pas = propertyInfo.Attributes;
propertyInfosPerName.Add(propertyInfo.Name,
propertyInfo);
}
string id = "thisisatest";
propertyInfosPerName["Identifier"].SetValue(theObject, id,
null);
propertyInfosPerName["Col1"].SetValue(theObject,
"col1ValTest", null);
propertyInfosPerName["Col2"].SetValue(theObject,
DateTime.Now, null);

((ActiveRecordBase)theObject).Save();

and get the following exception:

{"Could not perform Save for iTradeType1"}
Inner ex: {"Exception occurred getter of
Rbs.Gbm.Sgi.iTradeStorage.ValueObjects.iTradeType1.Identifier"}
Innder ex: {"Object does not match target type."}

at Castle.ActiveRecord.ActiveRecordBase.InternalSave(Object
instance, Boolean flush) in c:\TeamCity\buildAgent\work
\e41ee5ead2eba140\src\Castle.ActiveRecord\Framework
\ActiveRecordBase.cs:line 601
at Castle.ActiveRecord.ActiveRecordBase.Save(Object instance) in c:
\TeamCity\buildAgent\work\e41ee5ead2eba140\src\Castle.ActiveRecord
\Framework\ActiveRecordBase.cs:line 510
at Castle.ActiveRecord.ActiveRecordBase.Save() in c:\TeamCity
\buildAgent\work\e41ee5ead2eba140\src\Castle.ActiveRecord\Framework
\ActiveRecordBase.cs:line 1547
at
Rbs.Gbm.Sgi.iTradeStorage.ObjectManagement.ObjectManager.StoreObject(String
objectXml) in C:\Development\Rbs.Gbm.Sgi\iTradeStorage\ObjectManagement
\ObjectManager.cs:line 58
at ObjectManagementTests.ObjectManagerTests.StoreObjectTest() in C:
\Development\Rbs.Gbm.Sgi\iTradeStorage\Tests\ObjectManagementTests
\ObjectManagerTests.cs:line 78


Can somebody kindly help?

I'd like to try and debug the active record source code but can't seem
to find it. Where canI get ahold of it?

Thanks.

Nicholas Kilian

unread,
Jun 10, 2011, 6:24:06 AM6/10/11
to castle-pro...@googlegroups.com
I actually had this same problem the other day, eventually found an obscure
reference to the actual error in an NH bug report.

You need to handle the AppDomain.CurrentDomain.AssemblyResolve event and
return your compiled assembly - do this before initialising ActiveRecord.

((ActiveRecordBase)theObject).Save();


Can somebody kindly help?

Thanks.

--
You received this message because you are subscribed to the Google Groups
"Castle Project Users" group.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to
castle-project-u...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/castle-project-users?hl=en.

Regis Dubois

unread,
Jun 10, 2011, 7:29:55 AM6/10/11
to Castle Project Users
Hi and thanks Nicholas,

I am not sure I understand the solution you propose?
Plus the entire purpose of the exercise for me, is to dynamically
create assembly AFTER the active record initialization and to register
it after it's been compiled on the fly.

Note that I have tried to explicitly add the class to the solution in
order to test the following code:

ActiveRecordStarter.RegisterTypes(typeof(iTradeType1));
iTradeType1 it = new iTradeType1();
it.Identifier = "DummyId";
it.Col2 = DateTime.Now;
it.Save();

and it works.

So it's definitely something to do with AC or NH beeing unhappy with
the assembly I have compiled. I am trying to check the assembly
manifest, without much luck.

Any other suggestions are welcomed.

On Jun 10, 11:24 am, Nicholas Kilian <nicholaskil...@googlemail.com>
wrote:

Nicholas Kilian

unread,
Jun 10, 2011, 7:32:28 AM6/10/11
to castle-pro...@googlegroups.com
How is AR/NH meant to know about your type if it's not part of the
initialisation?

The problem is with NH and how it loads assemblies during configuration,
which is why you should handle the AssemblyResolve event and return your
runtime compiled assembly.

Regis Dubois

unread,
Jun 10, 2011, 7:45:46 AM6/10/11
to Castle Project Users
you can register assemblies and types after the initializarion:

ActiveRecordStarter.RegisterAssemblies(typeAssembly);

works fine. (I can create a table but can't save the object).

Can you please give me some sample code to see what you've put in the
AssemblyResolve event handler?

On Jun 10, 12:32 pm, Nicholas Kilian <nicholaskil...@googlemail.com>
wrote:

Nicholas Kilian

unread,
Jun 10, 2011, 8:05:23 AM6/10/11
to castle-pro...@googlegroups.com
Public Property CurrentAssembly As Reflection.Assembly
Public Property CurrentAssemblyName As String
Public Property CurrentAssemblyFullName As String

Public Sub New(ByVal asm As Reflection.Assembly)
''Code to set properties.
AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf
ResolveAssembly
End Sub

Private Function ResolveAssembly(ByVal sender As Object, ByVal e As
ResolveEventArgs) As Reflection.Assembly
If e.Name = CurrentAssemblyName Or e.Name = CurrentAssemblyFullName
Then
Return CurrentAssembly
End If
End Function

Regis Dubois

unread,
Jun 10, 2011, 8:16:45 AM6/10/11
to Castle Project Users
Done this but does not work - thanks anyway

On Jun 10, 1:05 pm, Nicholas Kilian <nicholaskil...@googlemail.com>

Markus Zywitza

unread,
Jun 10, 2011, 12:13:57 PM6/10/11
to castle-pro...@googlegroups.com
The exception sounds like it needs an integer id, since [PrimaryKey] is a shortcut for using Identity.

You can also try [PrimaryKey(PrimaryKeyType.Assigned)] instead.

-Markus

Regis Dubois

unread,
Jun 11, 2011, 5:58:26 AM6/11/11
to Castle Project Users
I tried to use int instead of string and it did not work either.

No that, as per my previous comment, if I create the type at compile
time iTradeType = new iTradeType, then it works fine. (see my other
comment June 10, 12:29)

The problem occurs only when I compile the assembly and register it
dynamically at run time.

As Nicholas suggested, it's probably something to do with how NH
handles assemblies.

I tried also the following without success:

AppDomain.CurrentDomain.AssemblyResolve += new
ResolveEventHandler(CurrentDomainAssemblyResolve);

private Assembly CurrentDomainAssemblyResolve(object sender,
ResolveEventArgs args)
{
if (_assembliesPerName.ContainsKey(args.Name))
{
return _assembliesPerName[args.Name];
}
return null;

Nick Kilian

unread,
Jun 11, 2011, 6:02:59 AM6/11/11
to castle-pro...@googlegroups.com

Reg,

Attach a failing project that does the dynamic compile and I'll have a look. I did some other fixes with regards registering the dynamically compiled types, so there may be something I'm doing that I can't recall fixed your particular problem.

Regards
Nick

Regis Dubois

unread,
Jun 11, 2011, 9:12:16 AM6/11/11
to Castle Project Users
I have started a new topic for this, thanks.


http://groups.google.com/group/castle-project-users/browse_thread/thread/3123896c4cc08f59

On Jun 11, 11:02 am, Nick Kilian <nicholaskil...@googlemail.com>
wrote:
> Reg,
>
> Attach a failing project that does the dynamic compile and I'll have a look.
> I did some other fixes with regards registering the dynamically compiled
> types, so there may be something I'm doing that I can't recall fixed your
> particular problem.
>
> Regards
> Nick
Reply all
Reply to author
Forward
0 new messages