Redirecting Assembly Binding

  • Thread starter Thread starter Mark Olbert
  • Start date Start date
M

Mark Olbert

I've been following what I >>thought<< was good practice and strong-naming my assemblies, even the ones that aren't targeted for
installation into the global assembly cache. I'm beginning to think, though, that this is a mistake.

The problem comes about when the assemblies used by an application are updated and distributed separately from the application
itself. In my case this happens because I don't want to force users to download the core application when the "only" thing I've
changed is a supporting assembly.

Unfortunately, the application's manifest expects a particular version of a strong-named assembly, and when it doesn't find that
particular version -- because, say, the user has downloaded a more recent version which doesn't change the interface but does fix a
bug -- it throws an exception.

I understand that this can be resolved through the app.config file, but that introduces another chance for error, and, besides, it
can get kind of cumbersome if there are a lot of assemblies that need to be redirected.

What would be nice is some way of saying "Dear application: I know these are strong-named assemblies, but I want you to use whatever
version you find in the application executable's directory". Is it possible to do that through some app.config setting? Or by using
some other approach?

- Mark
 
Hi Mark,

From your description, I understand that you want to know how to make the
application to bind to another version of strongnamed assembly.
Have I fully understood you? If there is anything I misunderstood, please
feel free to let me know.

I think we can use the <bindingRedirect> Element in the app.config file to
instruct the .NET runtime to binding to a new version.
<bindingRedirect> Element
http://msdn2.microsoft.com/en-us/library/eftw1fys.aspx

Redirecting Assembly Versions
http://msdn2.microsoft.com/en-us/library/7wd6ex19.aspx

Because once an application is binding to a strong named assembly, it will
check the Full Qualified Name to judge if a match assembly is found. Once
the culture, version or anything else is not match, the binding will fail.

So another approach for your scenario is to use a private assembly(not
strongnamed assembly) so that it will not do such strict check when binding
an assembly.

If you still have any concern, please feel free to post here.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Peter,

I'm (somewhat) familiar with the bindingRedirect element.

What I'm looking for is something which configures an application to ignore the versioning information in a strong-named assembly.
Without having to maintain a large list of bindingRedirect elements.

I don't want to stop strong-naming the assemblies because doing so identifies them as coming from me.

- Mark
 
Hi Mark,

Based on my research, the fusion.dll which is component of .NET framework
will match Full Qualified Name of the strong named DLL. This is by design
inside the CLR implement so far.

As you said, the strongnamed DLL is an evidence to prove its unique
identity. But a strongly named assembly consists of four attributes that
uniquely identify the assembly: a filename(without an extension), a version
number, a culture identity and a public key token(a value derived from a
public key).
For detailed information you may refer to books.
Applied Microsoft .NET Framework Programming (Paperback)
by Jeffrey Richter

See Section"Giving an Assembly a Strong Name", Charpter 3.

The located assembly's manifest definition with name xxx.dll does not match
the assembly reference
http://blogs.msdn.com/junfeng/archive/2004/03/25/95826.aspx

So the bindingredirect element is used in this scenario to instruct the CLR
to bind to a new DLL when it request for an old one.

Also since .NET support side-by-side execution, which means that we may
have one assembly of multiple versions on the same machine.
Because .NET will probe multiple places for an assembly binding.
e.g. there is strong named assembly A has a version 1.0.0.0 in GAC, but it
also have another version 2.0.0.0 in appbase.
So when binding time, which assembly CLR should bind to? the version
1.0.0.0 or 2.0.0.0? If we ignore the version attribute, that will cause the
..NET fusion mechanism confused.

If you still have any concern, please feel free to post here.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Peter,

I'm not confused, but my question is still unanswered: is there a way to configure an application to use only those strong-named
assemblies it finds in a specific directory (which would likely be the application directory, but doesn't have to be)? Without using
a ton of bindingRedirect statements, or giving up the strong name?

- Mark
 
Hi Mark,

I am afaid that the Answer is NO.
The CLR runtime will check all the four attributes of a strong named
assembly.
a filename(without an extension), a version number, a culture identity and
a public key token(a value derived from a public key).
Any part did not match will cause the binding to fail.

This is how CLR did inside. You may refer to my last post about why?

If you do want to change the behavior, I think you may try to submit a
feedback at out website.

Product feedback.
http://lab.msdn.microsoft.com/productFeedback/Default.aspx

BTW: you may try to implement your own CLR which is not a trivial.
But here is book for your reference.
Customizing the Microsoft .NET Framework Common Language Runtime
(Pro-Developer (Paperback)) (Paperback)
http://www.amazon.com/gp/product/0735619883/104-2217314-9888744?v=glance&n=2
83155

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Mark Olbert said:
Peter,

I'm not confused, but my question is still unanswered: is there a way to
configure an application to use only those strong-named
assemblies it finds in a specific directory (which would likely be the
application directory, but doesn't have to be)? Without using
a ton of bindingRedirect statements, or giving up the strong name?

- Mark

Once you strong name your application then all assemblies that it binds to
must also be strong-named. There is no way to automatically tell the runtime
to allow binding to any version it happens to find, but there are things you
can do to reduce the pain. For one, when you use binding redirects you can
specify a range of versions to redirect, so instead of needing a redirect
for every possible version number you can specify a range. For example, it
looks like this...
<bindingRedirect oldVersion="0.0.0.0-2.0.1.1" newVersion="2.0.1.1" />
which tells the runtime to redirect all versions between 0 and 2.0.1.1 to
2.0.1.1.

If you don't want to use binding redirects then you can instead subscribe to
the AssemblyResolve event and manually load whatever version assembly you
happen to find. You should try to load it using Assembly.Load rather than
LoadFrom to avoid putting the assembly into the LoadFrom context. As long
as the assembly is in the application base directory then there should be no
problems with loading it using Load.

Dave
 
Back
Top