Assemblies

W

whytwelve13

I have three projects. Project A is a class library. Project B is a
class library that uses project A. Project C is a Windows application
that uses both A and B. Project B is out of my control (I don't have
the source code), but I have a source code for project A and I can make
changes to it.

When both PA and PB are compiled as strongly-named assemblies,
everything works. In order to compile PA, I have to use my key file,
which is not the same as the key used for signing PA and PB when they
come together. This creates a strongly-named assembly pa.dll which
doesn't have the same public key token as the one that naturally comes
with PB.

Can I specify somehow in Project C that I want pb.dll to work with
pa.dll which I built? This means that the full assembly name will not
have it's version part changed, but the public token part instead.
Using bindingRedirect in app.config can solve pa.dll being upgraded to
another version, but how can I specify that I want another public
token?

Basically, without this possibility, if one library uses another one, I
have to have the source code for both or I cannot use them at all.

If I am mistaken in any of the above statements, please correct me.
Otherwise, do you have any ideas how this can be done?
 
C

Carl Daniel [VC++ MVP]

I have three projects. Project A is a class library. Project B is a
class library that uses project A. Project C is a Windows application
that uses both A and B. Project B is out of my control (I don't have
the source code), but I have a source code for project A and I can
make changes to it.

When both PA and PB are compiled as strongly-named assemblies,
everything works. In order to compile PA, I have to use my key file,
which is not the same as the key used for signing PA and PB when they
come together. This creates a strongly-named assembly pa.dll which
doesn't have the same public key token as the one that naturally comes
with PB.

Can I specify somehow in Project C that I want pb.dll to work with
pa.dll which I built?

No, you cannot. Being able to do so would totally defeat the whole purpose
of strong-named assemblies.
This means that the full assembly name will not
have it's version part changed, but the public token part instead.
Using bindingRedirect in app.config can solve pa.dll being upgraded to
another version, but how can I specify that I want another public
token?

You can't.
Basically, without this possibility, if one library uses another one,
I have to have the source code for both or I cannot use them at all.

Or you have to use them as a set as they were distributed to you. The whole
point of having strong-named assemblies is specifically to prevent exactly
what you're trying to do - changing the implementation of a library (A) that
another library that you don't control (B) depends on.
If I am mistaken in any of the above statements, please correct me.
Otherwise, do you have any ideas how this can be done?

Don't use strong named assemblies. If you need to use B, then you need to
use the exact version of A that B was built for.

-cd
 
W

whytwelve13

Thank you for your reply.
Or you have to use them as a set as they were distributed to you.
Yes, that is the third option. However, there is a need to change
something in PA in my case, I forgot to mention that, so this is not
really an option.
No, you cannot. Being able to do so would totally defeat the whole purpose
of strong-named assemblies.
The whole
point of having strong-named assemblies is specifically to prevent exactly
what you're trying to do - changing the implementation of a library (A) that
another library that you don't control (B) depends on.

I understand the reasoning behind strong-named assemblies and why this
is like it is. I was just thinking that user itself could override this
if he wanted. To make a parallel, this is the same as casting in OO
languages - you intentionally change a type of some object, because you
are sure it is going to work. I thought this would be true also in this
case - you would intentionally say pb.dll to use pa.dll. pb.dll's
integrity will not be affected by this, as you wouldn't be able to e.g.
ship the new pa.dll/pb.dll pair as a replacement for the old
pa.dll/pb.dll pair.

This doesn't sound like an integrity breach to me and would allow
things like I am trying to do. Are there any other problems about this
that I don't see?

I am thinking this might have been done to disallow external libraries
to be used with custom code, but in my case both projects are "ours",
so this is not something illegal in that sense. The only thing is that
I myself do not have a simple way to get pb.dll compiled against my
pa.dll - not impossible, but very slow and thus painful. Just trying to
make this process easier.
Don't use strong named assemblies. If you need to use B, then you need to
use the exact version of A that B was built for.

OK, considering the above cannot be done, is there a way to make the
shipped pb.dll weakly named and make it use weakly named pa.dll? Can I
say - OK, here is pb.dll, let's strip strong name info, let's build
pa.dll from the source I have and then I can use both weakly named
dll's together? Or anything in this regard that would allow the above?

Thanks again!
 
C

Carl Daniel [VC++ MVP]

Thank you for your reply.

You're welcome.
OK, considering the above cannot be done, is there a way to make the
shipped pb.dll weakly named and make it use weakly named pa.dll? Can I
say - OK, here is pb.dll, let's strip strong name info, let's build
pa.dll from the source I have and then I can use both weakly named
dll's together? Or anything in this regard that would allow the above?

Yes, there is. Assuming it's pure IL (not a C++ mixed mode dll), you can
disassemble it using ILDASM and re-assemble it using ILASM. The resulting
DLL will be identical but not strong-named. Logically there must be a way
to do it for a mixed mode DLL as well, but I don't think a round-trip
through ILDASM/ASM will do it.

-cd
 

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