Unit testing c# code in a ScriptSharp project - c#

Im using ScriptSharp to create a RIA app.
Works nice besides some oddities.
However finding and fixing problems using Firebug isn't really convinient.
Since scriptsharp also delivers a Dll I was hoping to use a separate testproject using Nunit to test some parts of my code.
Issue that arises is that the generated dll references mscorlib 0.7 resulting in conflict with mscorlib 4 in the test project.
A simple solution is to create a second plain C# project and copy codefiles around. But maintaining 2 projects with the same code base...
Curious if there is another way to do this. Anybody?
EDIT:
Solution as proposed by Christian Dalager works.
Small thing is that ScriptSharp has redefined System.Diagnostics in mscorlib. No more Debug.Assert/Writeline. But there is almost no more need for it now.

You might try using assembly binding redirects
You would put something like this in the app.config on your testproject.
Havent tested this particular configuration, so you will need to adjust it.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v1.0.3705">
<dependentAssembly>
<assemblyIdentity name="mscorlib" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.7.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>

Related

Why are there Different versions info for the same DLL?

I recently had my first encounter with Could not use file or assembly version issue. And I had some understanding How and Why assemblyBinding>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="4.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
But I am still not sure about the usage of other versions info?
Q:- what is the use of Runtime version(red box), the File Version(yellow box) and any other use of Green box?
Noob Q:- Why can't we have one unique version for each DLL?
what is the use of Runtime version(red box)
This is the runtime that will be used by this reference. This will always be 4.0.30319 for .Net 4.8 references, and any other .Net framework 4.x reference. Since .Net framework 3.x and earlier is uncommon these days I do not think this is very useful anymore. I do not think this is even displayed for .Net standard/core projects.
the File Version(yellow box) and any other use of Green box
The file version, product version, and version in the reference box, all uses different fields in the file. So there is nothing that says they have to be the same. But if you just create a regular library project and build a dll, the compiler should set all of them to the same value. It is usually fairly simple with pure .Net dlls, but other types of dlls can have different versioning practices to make things more complicated.
Why can't we have one unique version for each DLL?
I'm not sure what exactly you mean by this. But versioning is difficult. A common problem occur when libraries use different versions of a third library. It is possible the two versions are different in some regards, and any way you can handle this risks breaking something.
I would recommend reading John Skeet's article on Options for .NET’s versioning issues for better insight into the potential problems.

C# asp.net Supporting multiple versions of a dll

I have the following dll hell:
a ASP.Net project
references WebGrease
which references Antlr3.Runtime.dll 3.3.1.7705 [stored in /bin/ folder of the asp.net app]
references Custom project
which references NCalc.codeplex.com
which references Antlr3.Runtime.dll 3.1.3.22795 [stored in /bin/CustomProject/ folder of the asp.net app]
unsurprisingly these two version of Antlr are not working well together and I get "The located assembly's manifest definition does not match the assembly reference" errors
I am unwilling to modify the WebGrease project.
I am attempting to upgrade the NCalc project to use 3.3.1.7705 however I am struggling with this
Do you have any suggestions on how to get these two DLL's to work together?
EDIT unfortunately the NCalc code is not compatible with the newer version of antlr so I cannot used binding redirects
Thank you
Providing NCalc can use the later version of Antlr3.Runtime - ie there are no breaking changes you should be able to use a binding redirect to direct it to load the later version
eg in the web.config file ass something like
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NCalc" publicKeyToken="xxxxxxxxx" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.3.0" newVersion="3.3.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
I don't think the 4th digit on the versions is used

MVC Contrib VerificationException

I have read this post and I wanted to use ControllerExtensions.RedirectToAction method. But I have System.Security.VerificationException Which says: type argument '[MyController type]' violates the constraint of type parameter 'T'.
My controller is declared as follows:
public class ProductsSearchController : Controller
{
...
}
Help me, please.
Also I tried to download the latest MvcContrib library from here. It didn't help me.
I noticed an interesting fact. I have this exception only when calling from unit tests. But there is no exception when using from web site. However it seems not working correctly. When I pass an object to the action in expression like this:
this.RedirectToAction(x => x.Index(filter))
it just call .ToString of this object! And I get url like this:
ProductsSearch?filter=WebShop.FinderModel.Filters.ProductsFilter
What is wrong?
I've been having this problem.
I was using MvcContrib version 2.0.95.0 alongside System.Web.Mvc version 4.0.30319.
The problem was that MvcContrib references an earlier version of System.Web.Mvc.
If you're using an older version of MvcContrib with Mvc 2 it should be sufficient to download and reference the latest version of MvcContrib. If you're using .NET 4 and Mvc 3 you'll need to update the App.Config file for your unit test project (you may have to add one) with the following:-
<configuration>
...
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
....
</configuration>
Bear in mind that you may need to change the version numbers if you're using a different version of MVC. (e.g. at the time of this edit you'd need to use oldVersion="1.0.0.0-5.1.0.0" and newVersion="5.2.0.0").
You may also need to add this to your web project. If you're only getting the exception in your test project, chances are this section already exists and is correct in your web.config; you can copy and paste it from there.
If you're using Code Analysis, you'll also need to see Assembly Binding Redirection and Code Analysis in order for it to respect the binding redirection.

adding COM dll as a reference from specific location

I am posting this query again.Soory, but I dont know how to ask doubts about already asked query.
I am using a COM dll as a reference in my Project. I want that dll to be referenced from any location of computer.
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="MyAssembly" culture="" publicKeyToken="8968ee41e78ce97a" /> <codeBase version="1.0.0.0" href="file://c:/some_path/myassembly.dll" /> </dependentAssembly> </assemblyBinding></runtime>
I have added above mentioned code in App.config file. After signing the Interop.Microsoft.Office.Interop.Excel.dll which was unsigned earlier,I have given proper value for PublicKeytoken.
This I think works fine.
but when i run the application the exe expects the dll to present in same folder & that too
the unsigned version.
Can anyone suggest me, if there is anything which i am missing in my code?
Thanks,
Amit
PS: During coding, I had added reference of unsigned version of dll. from C:\Program files...\ [Already existing dll, microsoft provided]
This is only a guess without reproducing your exact situation... It appears your missing the
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
In all the examples I've seen as well as all my uses of this, the above <assemblyIdentity...> tag is always followed by a <bindingRedirect ...>. BTW, You can also specify the original version as a range like the following:
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="2.0.0.0"/>
I think i have got the solution. As i mentioned in my question, I had added reference of older[unsigned] version of dll. I removed that & added reference of signed dll,then made changes into App.config[mentioned in my question].

Referencing different versions of the same assembly

If A references assembly B 1.1 and C, and C references B 1.2, how do you avoid assembly conflicts?
I nievely assumed C's references would be encapsulated away and would not cause any problems, but it appears all the dll's are copied to the bin, which is where the problem occurs.
I understand the two ways around this are to use the GAC or assembly bindings? The GAC doesn't seem like the best approach to me, as I don't like assuming dlls will be there, I prefer to reference dlls from a lib directory in my solution.
Where as assembly bindings don't seem robust to me, what if one version of the assembly has functionality that the other doesn't, will this not produce problems?
In my case its because I'm using a 3rd party dll uses a older version of nHibernate, than I'm using myself.
I've achieved the same results using the GAC in the past, but you should question your reasons for having to reference more than one version and try to avoid it if possible. If you must do it, a binding redirect may help in your case.
Also, have you read this yet?
A seemingly little known way of doing this is to use the extern keyword.
From C# Reference
To reference two assemblies with the same fully-qualified type names,
an alias must be specified at a command prompt, as follows:
/r:GridV1=grid.dll
/r:GridV2=grid20.dll
This creates the external aliases GridV1 and GridV2. To use these
aliases from within a program, reference them by using the extern
keyword. For example:
extern alias GridV1;
extern alias GridV2;
Each extern alias declaration introduces an additional root-level
namespace that parallels (but does not lie within) the global
namespace. Thus types from each assembly can be referred to without
ambiguity by using their fully qualified name, rooted in the
appropriate namespace-alias.
In the previous example, GridV1::Grid would be the grid control from
grid.dll, and GridV2::Grid would be the grid control from grid20.dll.
I was required to support multiple versions of an assembly and found this solution:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly" publicKeyToken="..." />
<codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
<codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
You can add a bindingRedirect element to your configuration file to specify which version of the assembly you want to use at runtime.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
The .NET runtime is perfectly capable of loading multiple versions of the same assembly simultaneously. If you are going to open this can of worms, however, I strongly suggest you stronly name your assemblies and use the Major.Minor.* naming scheme to avoid naming conflicts.
I don't think you should think of a one-size-fits-all approach to using (or not) the GAC. The GAC can be really nice if you want to automagically use new functionality published with future versions of a DLL. Of course, this blessing comes at a cost that new versions might not work exactly like you expect them too :). It's all a matter of what's most practical, and how much control you have over what gets published to the GAC.
Regards,
-Alan.

Categories