Top .net-4.0 Questions

List of Tags

I have a project in which I'd like to use some of the .NET 4.0 features but a core requirement is that I can use the System.Data.SQLite framework which is compiled against 2.X. I see mention of this being possible such as the accepted answer here but I don't see how to actually achieve this.

When I just try and run my 4.0 project while referencing the 2.X assembly I get:

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

What "additional configuration" is necessary?

Answered By: Reed Copsey ( 335)

In order to use a CLR 2.0 mixed mode assembly, you need to modify your App.Config file to include:

<?xml version="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

The key is the useLegacyV2RuntimeActivationPolicy flag. This causes the CLR to use the latest version (4.0) to load your mixed mode assembly. Without this, it will not work.

Note that this only matters for mixed mode (C++/CLI) assemblies. You can load all managed CLR 2 assemblies without specifying this in app.config.

For Visual Studio 2010 Web based application we have Config Transformation features by which we can maintain multiple configuration files for different environments. But the same feature is not available for App.Config files for Windows Services/WinForms or Console Application.

There is a workaround available as suggested here: Applying XDT magic to App.Config.

However it is not straightforward and requires a number of steps. Is there an easier way to achieve the same for app.config files?

Answered By: Scott Hanselman ( 167)

This works now with the Visual Studio AddIn treated in this article: SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file.

161
Reed Copsey

The ExpandoObject class being added to .NET 4 allows you to arbitrarily set properties onto an object at runtime.

Are there any advantages to this over using a Dictionary<string,object>, or really even a Hashtable? As far as I can tell, this is nothing but a hash table that you can access with slightly more succinct syntax.

For example, why is this:

dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);

Really better, or substantially different, than:

var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);

What real advantages are gained by using ExpandoObject instead of just using an arbitrary dictionary type, other than not being obvious that you're using a type that's going to be determined at runtime.

Answered By: Alexandra Rusina ( 202)

Since I wrote the MSDN article you are referring to, I guess I have to answer this one.

First, I anticipated this question and that's why I wrote a blog post that shows a more or less real use case for ExpandoObject: Dynamic in C# 4.0: Introducing the ExpandoObject.

Shortly, ExpandoObject can help you create complex hierarchical objects. For example, imagine that you have a dictionary within a dictionary:

Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] = "WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

The deeper is the hierarchy, the uglier is the code. With ExpandoObject it stays elegant and readable.

dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);

Second, as it was already pointed out, ExpandoObject implements INotifyPropertyChanged interface which gives you more control over properties than a dictionary.

Finally, you can add events to ExpandoObject like here:

class Program
{

   static void Main(string[] args)
   {
       dynamic d = new ExpandoObject();

       // Initialize the event to null (meaning no handlers)
       d.MyEvent = null;

       // Add some handlers
       d.MyEvent += new EventHandler(OnMyEvent);
       d.MyEvent += new EventHandler(OnMyEvent2);

       // Fire the event
       EventHandler e = d.MyEvent;

       if (e != null)
       {
           e(d, new EventArgs());
       }

       // We could also fire it with...
       //      d.MyEvent(d, new EventArgs());

       // ...if we knew for sure that the event is non-null.
   }

   static void OnMyEvent(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent fired by: {0}", sender);
   }

   static void OnMyEvent2(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
   }
}
158
Omar

I'm running Windows 7 Ultimate (64 bit) using Visual Studio 2010 RC. I recently decided to have VS run/debug my apps on IIS rather than the dev server that comes with it.

However, every time I try to run an MVC app, I get the following error:

HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory. Detailed

Error Information

Module DirectoryListingModule

Notification ExecuteRequestHandler

Handler StaticFile Error

Code 0x00000000 Requested

URL http://localhost:80/mySite/

Physical Path C:\myProject\mySite\

Logon Method Anonymous Logon

User Anonymous

I placed a default.aspx file in the directory and I received the following error:

HTTP Error 500.21 - Internal Server Error Handler "PageHandlerFactory-Integrated" has a bad module "ManagedPipelineHandler" in its module list

Are there any other steps I forgot to take to get this working?

Notes: I installed IIS 7.5 after installing VS 2010 RC. I used the built-in "Create Virtual Directory" button under the "Web" tab in the MVC project's "Properties" in Visual Studio 2010. I made sure that the application is using the ASP.NET 4 App Pool.

Below are the installed features of IIS I have.

alt text

Answered By: Omar ( 265)

ASP.NET 4 was not registered in IIS. Had to run the following command in the command line/run

32bit (x86) Windows

%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -ir

64bit (x64) Windows

%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -ir

Note from David Murdoch's comment:

That the .net version has changed since this Answer was posted. Check which version of the framework is in the %windir%\Microsoft.NET\Framework64 directory and change the command accordingly before running (it is currently v4.0.30319)

158
Max Toro

%windir%\Microsoft.NET\assembly\ is the new GAC. Does it mean now we have to manage two GACs, one for .NET 2.0-3.5 applications and the other for .NET 4.0 applications?

The question is, why?

Answered By: Brian R. Bondy ( 90)

Yes since there are 2 distinct Global Assembly Cache (GAC), you will have to manage each of them individually.

In .NET Framework 4.0, the GAC went through a few changes. The GAC was split into two, one for each CLR.

The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. There was no need in the previous two framework releases to split GAC. The problem of breaking older applications in Net Framework 4.0.

To avoid issues between CLR 2.0 and CLR 4.0 , the GAC is now split into private GAC’s for each runtime.The main change is that CLR v2.0 applications now cannot see CLR v4.0 assemblies in the GAC.

Source

Why?

It seems to be because there was a CLR change in .NET 4.0 but not in 2.0 to 3.5. The same thing happened with 1.1 to 2.0 CLR. It seems that the GAC has the ability to store different versions of assemblies as long as they are from the same CLR. They do not want to break old applications.

See the following information in MSDN about the GAC changes in 4.0.

For example, if both .NET 1.1 and .NET 2.0 shared the same GAC, then a .NET 1.1 application, loading an assembly from this shared GAC, could get .NET 2.0 assemblies, thereby breaking the .NET 1.1 application

The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. As a result of this, there was no need in the previous two framework releases to split the GAC. The problem of breaking older (in this case, .NET 2.0) applications resurfaces in Net Framework 4.0 at which point CLR 4.0 released. Hence, to avoid interference issues between CLR 2.0 and CLR 4.0, the GAC is now split into private GACs for each runtime.

As the CLR is updated in future versions you can expect the same thing. If only the language changes then you can use the same GAC.

The .NET 4 32 + 64 bit Full is 48.1 MB and the Client Profile is 41.0 MB.

When is it preferable to install the Client Profile instead of the full .NET Framework? What difference is there between the two packages?

Answered By: Cameron MacFarland ( 159)

This blog post explains many of the differences.

http://blogs.msdn.com/jgoldb/archive/2010/04/12/what-s-new-in-net-framework-4-client-profile-rtm.aspx

When to use NET4 Client Profile and when to use NET4 Full Framework?
NET4 Client Profile:
Always target NET4 Client Profile for all your client desktop applications (including Windows Forms and WPF apps).

NET4 Full framework:
Target NET4 Full only if the features or assemblies that your app need are not included in the Client Profile. This includes:

  • If you are building Server apps. Such as:
    o ASP.Net apps
    o Server-side ASMX based web services
  • If you use legacy client scenarios. Such as:
    o Use System.Data.OracleClient.dll which is deprecated in NET4 and not included in the Client Profile.
    o Use legacy Windows Workflow Foundation 3.0 or 3.5 (WF3.0 , WF3.5)
  • If you targeting developer scenarios and need tool such as MSBuild or need access to design assemblies such as System.Design.dll