Replacing an Assembly at runtime

A

Anton Maters

Hi,

I am having problems to get the AssemblyBuilder.Save work the way i want it.

My situation:
I am building an asp.net application which can be used my multiple clients.
All clients start off with the same base database. all aspx pages use a
certain dll (lets call it XNotGenerated.dll) to retrieve data. All classes
in the XNotgenerated Assembly inherit from a base class in another
assembly. This baseclass handles all the data retrieval by using Reflection.
So far everything works ok.
Every customer however has extra datafields in certain tables which need to
be reflected in the XNotGenerated Assembly. So I programmed a routine which
generates an assembly (lets call this one XGenerated.dll). This all works
very well. Altough i dont add a reference to the assembly where the
BaseClass is located it works. If i replace the XGenerated.dll with a newly
generated dll (in a test application) it keeps working

What doesn't work is generating the assembly from an aspx page. In that case
I get an "Access Denied" error when i call the AssmbleyBuilder.Save Method.
I already discovered it doesn't try to save the dll to the bin folder but
somewhere else. Anybody who can help me with how to do this?
Any help would be very appreciated.

Kind Regards,
Anton Maters
 
J

Jon Skeet [C# MVP]

What doesn't work is generating the assembly from an aspx page. In that case
I get an "Access Denied" error when i call the AssmbleyBuilder.Save Method.
I already discovered it doesn't try to save the dll to the bin folder but
somewhere else. Anybody who can help me with how to do this?
Any help would be very appreciated.

Just looking for the docs of AssemblyBuilder.Save, there's this:

<quote>
The assemblyFileName needs to be a simple file name without a drive or
directory component. To create an assembly in a specific directory, use
one of the DefineDynamicAssembly methods that takes a target directory
argument.
</quote>

Have you tried that?
 
M

Marc Gravell

It sounds like you are trying to swap the dll inside a live appdomain;
that is not going to work... you can have an additional assembly, or
you can do some tricks with System.ComponentModel to add virtual
properties (warning: this approach doesn't work with most ORM tools,
including LINQ and NHibernate). Or did I misunderstand and you somehow
have 2 appdomains here? Note that you don't need to save an assembly
to have it work... in memory is fine, and presents fewer security
concerns...

Marc
 
A

Anton Maters

Thanks. I did try it already and it gave me the same error. I think it was
just because i was not using the right call to get the bin directory. I
changed it to use Appdomain.CurrentDomain.BaseDirectory + "bin" and now it
works if I generate an assembly with a non-existing name.

So the problem remains how I can replace my Standard Assembly with the newly
generated one. If I try that it still gives me an error. As Marc stated this
would be impossible.
Any suggestions here?
I cannot work with just an in-memory Assembly. It has to be saved to disk
for future use.
 
J

Jon Skeet [C# MVP]

Anton Maters said:
Thanks. I did try it already and it gave me the same error. I think it was
just because i was not using the right call to get the bin directory. I
changed it to use Appdomain.CurrentDomain.BaseDirectory + "bin" and now it
works if I generate an assembly with a non-existing name.

So the problem remains how I can replace my Standard Assembly with the newly
generated one. If I try that it still gives me an error. As Marc stated this
would be impossible.
Any suggestions here?
I cannot work with just an in-memory Assembly. It has to be saved to disk
for future use.

Can you not just generate a new name each time? Without knowing more
about how it's all meant to work, it's tricky to advise, unfortunately.
 
P

Peter Bromberg [C# MVP]

Which AssemblyBuilderAccess enum value are you using? Is it necessary to
actually Save the assembly? Can't you use the AssemblyResolve event handler
to return it that way - from memory?
-- Peter
Site: http://www.eggheadcafe.com
UnBlog: htp://petesbloggerama.blogspot.com
Short Urls & more: http://ittyurl.net
 
A

Anton Maters

Hi,

Changes to the database are not frequent. so generating the assembly in
memory everytime is imho overhead we dont want.
The fact it needs to be regenerated now and then is that the database
structure is changed by another program which doesnt interact with the
website itself. This program changes the database structure now and then.
 
A

Anton Maters

Let me explain the situation.

i have a solutions with 3 projects:
- Web application
- XGen class library
- XBase class library

The web application has a reference to both class libraries
the XGen class library has a reference to XBase.
XBase handles dynamic data retrieval to from the database and is able to
regenerate the XGen class library.

The database structure will be changed by another desktop application which
is not written in dotnet.
At some point our client recieves an update of the desktop application. When
they run it first time the database structure is automatically updated.
When this happens the web application must have the abbility to regenerate
the XGen assembly and replace the old one with the newly generated one.

At some point the client can request new features for their web application.
We then take the last generated assembly for their specific situation an
develop custom features for them.

I hope i have given you a good description of why i have chosen this way.
 
M

Marc Gravell

You'd get on well with Andrus ;-p

I must admit, I'm not a fan of this particular type of setup, but...
in this scenario, could a utility app not generate the assembly and
store *inside* the database as a BLOB? Then your web app could use
AppDomain.AssemblyResolve to provide the assembly out of the database?
Of course, dynamic generation wouldn't take long, so perhaps just
generate it on the fly...

Marc
 
A

Anton Maters

Well, in fact we are thinking about 1 Admin wep application which woul be
our "control panel" to monitor customers. There we could handle the
generation of customized assemblies and put them in the web application of
the client.
 
A

Andrus

Changes to the database are not frequent. so generating the assembly in
memory everytime is imho overhead we dont want.
The fact it needs to be regenerated now and then is that the database
structure is changed by another program which doesnt interact with the
website itself. This program changes the database structure now and then.

You can generate assembly in memory every time. It does not take a lot of
time.
You can also cache generated assembly or its data source in isolated
storage.

In AssemblyResolve event you can return this generated assembly reference,
possibly using cached data from isloated storage.

Andrus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top