in

Dé specialist in .NET trainingen en consultancy

Thomas Huijer - Compiler says no....

  • WCF and LINQ: beware of deferred execution

    When I was teaching WCF in Oslo this week, a student got an Exception from the client when calling this method on the server:
     
    public IEnumerable<Product> GetProductsForProductModel(int productModelID)         
    {
      using (AdventureWorks2008R2Entities context = new AdventureWorks2008R2Entities())
      {
        return
          from Product p in context.Product
          where p.ProductModel.ProductModelID == productModelID
          select p;
      }
    }
    

    At first there seemed nothing wrong with the code and I assmumed it was caused by the maxReceivedMessageSize setting. But increasing that didn’t help. Then it struck me…we are returning a query and not a resultset. So when the DataContractSerializer started to fetch the results from the query (when it was serializing our result), the used ObjectContext was already disposed. When we enabled Tracing and MessageLogging we found out that this was indeed the case: we got an ObjectDisposedException from the ObjectContext. The fix was easy, calling ToList() on the query before returning did the trick…

    Deferred execution is a great feature…sometimes it just bites you.

  • WCF Service in PreCompiled ASP.NET web application

    I got an email from a customer that reported a bugin the Web Deployment Tool 2010. Maybe it saves you some time if you ever encounter this. This is the translated text:

     

    When we deploy our webapplication, we precompile it first using the Web Deployment Tool 2010. While testing, we found out that the service could not be located. After some digging it turned out the problem was in the .compiled file of the service.

    See this post fromTom Fuller : http://social.msdn.microsoft.com/forums/en-US/wcf/thread/8c897f8e-2143-450e-a9f4-97d1f8702da7

    We solved it by using MSBuildTasks in the Web Deployment project (http://msbuildtasks.tigris.org/

    With that, we replacing the absolute location of the file with the “~” sign.

    <FileUpdate Files="..\..\Output\Web\Deployment\bin\documentservice.svc.989dc2fb.compiled" Regex="/Donau Web.csproj" ReplacementText="~" />

    We also remove all references to the ASP.NET folders like “App_”:

    <FileUpdate Files="..\..\Output\Web\Deployment\bin\documentservice.svc.989dc2fb.compiled" Regex="\|App_global.asax, Version=0\.0\.0\.0, Culture=neutral, PublicKeyToken=417399dd0d17e25b\|" ReplacementText="|" />

        <FileUpdate Files="..\..\Output\Web\Deployment\bin\documentservice.svc.989dc2fb.compiled" Regex="\|App_GlobalResources, Version=0\.0\.0\.0, Culture=neutral, PublicKeyToken=417399dd0d17e25b\|" ReplacementText="|" />

  • Improving Legacy Code session at the DevDays 2011

    Demo's from my Improving Legacy Code session at the DevDays 2011 are available here: http://bit.ly/mNMJac
    PowerPoint-slides are here: http://bit.ly/lQuNCH

    Let me know if you have any questions at thomas@oosterkamp.nl

  • Caliburn Micro events without having to implement IHandle

    I like Caliburn.Micro. I like it a lot. I love the way it’s so small and compact and yet so powerful. Right now we’re using it in a Silverlight 4 project and I have yet to encounter something I really don’t like. Nonetheless….there’s something I felt was a bit more work than I liked: the way the EventAggregator works. Publishing an event is plain and simple: you just call Publish on the EventAggregator and pass it an instance of your event class:

    eventAggregator.Publish(new SendStringEvent() { Value = "Hi!" });
    

    If you want to subscribe to an event, you basically you have to implement IHandle<T> where T is the class that represents your event. This is how it’s usually done:

    public class MainPageViewModel : IHandle<SendStringEvent>
    {   
    public void Handle(SendStringEvent message)  
    {
          
    StringValue = "Received: " + ev.Value;   }

    Not too bad if you have just one or a few eventhandlers in your ViewModel. But your class declaration gets more cluttered with all IHandle<T> declarations if you have more than a few. I didn’t like that. I wanted to be able to add a lambda expression in the Subscribe method like this:

    eventAggregator.Subscribe<SendStringEvent>(
    ev => StringValue =
    "Received: " + ev.Value);

    The good news is is that I have found a real easy way to do that. Just three very simple classes are needed. First, I created a MessageHandler<T> that implements IHandle<T>. The constructor of MessageHandler<T> takes an Action<T> as an argument:

    public class MessageHandler<T>: IHandle<T>
    {
        
    private readonly Action
    <T> _messageHandler;
        
    public MessageHandler( Action
    <T> messageHandler )
         {
             _messageHandler = messageHandler;
         }
         public void Handle(T message)
         {
            
    if (_messageHandler != null)
                 _messageHandler(message);
         } }

    So, now I’m able to Subscribe to the event like this:

    eventAggregator.Subscribe<SendStringEvent>(
           
    new MessageHandler<SendStringEvent>(
    ev => StringValue =
    "Received: " + ev.Value) );

    Already better because I don’t have to implement IHandle<T> in my ViewModel anymore. But a bit more awkward to use than the original implementation. So I created a extension method on EventAggregator that made subscribing easier.

    public static class EventAggregatorExtension
    {
        
    public static void Subscribe<T>( this EventAggregator eventAggregator,
    Action
    <T> eventHandler )
         {
             eventAggregator.Subscribe(
    new MessageHandler<T>(eventHandler));
         }
    }

    And we’re done! Now we can subscribe to events like this:

    eventAggregator.Subscribe<SendStringEvent>(
         ev => StringValue =
    "Received: " + ev.Value);

    But wait…we’re not done. Because Caliburn Micro is using a list of WeakRefereces, the Garbage Collector will collect our MessageHandler objects! So message handlers will no longer be called after a garbage collection. So the ViewModel needs to maintain references to every MessageHandler<T> that it creates. In order to do that I created a MessageHandlerList. The ViewModel holds a reference to the MessageHandlerList and that holds references to each MessageHandler<T> that is created:

    public class MessageHandlerList
    {
       
    private List<object> list = new List<object
    >();
       
    private readonly EventAggregator
    _aggregator;
       
    public MessageHandlerList(EventAggregator
    aggregator)
        {
            _aggregator = aggregator;
    }
       
    public void Subscribe<T>(Action
    <T> eventHandler)
        {
            list.Add(_aggregator.Subscribe<T>(eventHandler));
        }
       
    public void Publish<T>(T message)
        {
            _aggregator.Publish<T>(message);
        }
    }

    So when we want to subscribe to multiple Messages, you first create a new MessageHandlerList and pass it an existing (or new) EventAggregator in the constructor. And then call Subscribe and Publish on the MessageHandlerList. Subscribing to Messages should be done through the MessageHandlerList, but Publishing messages can be done through the MessageHandlerList or the normal way using the EventAggregator directly:

    MessageHandlerList events = new MessageHandlerList(new EventAggregator());

    events.Subscribe<SendStringEvent>(ev => button2.Content += ev.Value);
    events.Publish(
    new SendStringEvent() { Value = "Hi!" });
  • Reporting Services 2008 without IIS

    When teaching a Reporting Services course today, I was told by an attendee that Reporting Services 2008 could be installed without the need for IIS. I read about that, but assumed that it had an internal webserver or something similar that you could activate if you didn’t have IIS (I guess I didn’t really read the documentation, I just made some assumptions). But the attendee pointed me to a webpage that showed how Reporting Services work without IIS. Instead of an internal webserver, Microsoft implemented Reporting Services 2008 as an extension to HTTP.SYS, called an HTTP Listener. That means that Reporting Services gets passed requests for it and IIS never gets those requests. This means that you actually have two processes reacting to requests on port 80. And that’s possible because HTTP.SYS is the process that actually listens on port 80 and hands those requests to either Reporting Services or IIS.

    Read more about it here.

  • Modifying the generated code from RIA Services

    Today at a client I had the need to modify the code that RIA Services generates. It is certainly possible, but not as easy as modifying a T4 template. It turns out you have to derive a class from System.ServiceModel.DomainServices.Server.CodeProcessor. If you put the DomainIdentifierAttribute on your DomainService class, you can specify your own CodeProcessor.

    The CodeProcessor gets an tree with the CodeDOM of the code that is going to be generated. The MSBuild task responsible for generating the code, hands that to your CodeProcessor so you can add, remove or change anything you want. See an example of a CodeProcessor here.

    I’ve read somewhere that the next version of RIA Services is going to support T4 Templates, but for now I can live with it.

  • Configure Windows to Log in to TFS Automatically

    After typing my TFS credentials about a million times, today I finally took the time to figure out how to log on to TFS automatically if the PC that I’m working on is not part of a (or not the same) Active Directory than the TFS server is. Turns out it’s pretty simple: http://blog.benday.com/archive/2007/10/10/23162.aspx

    Why haven’t I searched for that before?

  • Custom Dictionary for Code Analysis

    At the DevDays 2010 in my session on Building Maintainable Applications, a question came up how to add custom words to Code Analysis. I’ve done that a couple of times, but couldn’t remember it from the top of my had. So, this is just a note-to-self.

    1. Add a XML file (e.g. CustomDictionary.xml) to your project
    2. Set the Build Action to CodeAnalysisDictionary
    3. Set Copy to Output Directory to Do not copy

    If you put the xml file in the root install folder of Visual Studio, it’ll be applied to all projects. Alternatively, you could share a dictionary file using the Add as Link when adding files to a project.

  • Software Quality: External versus Internal

    I’m doing quite a lot of software quality audits lately. Some customers want to know what the quality is of a product that was developed off-shore. Some just want to know how long they should keep developing the current version or if they should start developing a new version in a new environment. Often products that have been around for long have architectures that are not kept into shape. Or new requirements that just won’t fit into the current architecture. Of requirements that are just too hard to do in the current environment, for example communicating with advanced webservices that require certificates, SSL, custom authentication or reliable sessions. For products developed with for example VB6, this is just extremely time-consuming to develop. While this is plain easy in WCF.

    Anyway, whatever the reason is that customers have to request an quality audit, I always first explain to them the difference between what I call the external and internal quality of a software product.

    • External quality
      This is the quality of the product that is perceived by the users of the product. This includes the stability of the product, the ease of use of it, the interaction design and the way it conforms to the requirements
    • Internal quality
      This is the quality of the source code, the quality of the architecture, the quality of the development process around the product, etc. Anything that is not perceivable by the users of the software.

    We at Oosterkamp training | consultancy are specialized in auditing the internal quality of software. We have developed our own techniques for quickly and accurately determining the internal quality of software. For example, we look at how clean the code is. We also inspect software for possible defects in software using IfSQ. We look at the architecture of the software, the consistency of used solutions, etc., etc.

    Call us if you’re interested in an audit or are interested in reviews of audits we did for our customers.

  • MVP C# in 2010

    I was notified today by email that Microsoft awarded me the 2010 Microsoft MVP Award for C#.

    Just great!

  • MSTest: Cannot start more than one local run

    When I run my tests in Visual Studio and one or more tests fail, I hit the Debug Selected Test so see what is going on. But at times, I get this error message:

    image

    I don’t know what trigger this, but I had to restart Visual Studio to be able to Run or Debug tests again. After some searching on the net, I found out that there’s some sort of communication error between Visual Studio and the executable that actually runs the tests. So my resolution now is to kill that process and try again. The name of the executable to look for is VSTestHost.exe. Kill the process and you’re good to go…

    image

  • Chad Hower’s story

    A friend of mine, Chad Hower aka Kudzu, is in trouble. Chad has developed many internet-related components for Delphi, with Indy (being shipped with Delphi) being the most well known. Chad is also a speaker and writer and now works for Microsoft. He’s accused of kidnapping his son. Although there’s really strong evidence that it’s totally impossible for him to have done so. For example, how can you kidnap a son you have custody over? It’s a heartbreaking and quite unbelievable story. Watch the 5 minute at www.freechad.org and spread the word!

  • What’s new in WCF 4.0: brief summary

    Below are the notes I took at the PDC about what’s new in WCF 4.0.

    • Default bindings can be created. If no bindings are specified for a service, these bindings are used.
    • WCf supports configuration inheritance, so bindings could also be specified at various levels including the machine.config.
    • Same applies to behaviors
    • Default bindings/behaviors are the bindings/behaviors that have no name or name=”” in the configuration
    • Configuration based activation allows services without *.svc files
    • ETW (Event Tracing for Windows) is used by WCF
    • AppFabric (FKA “Dublin”) stores that data in a Sql Server database for easy retrieval and querying.
    • Routing is a completely new feature in WCF which allows service aggregation, protocol bridging and versioning.
    • MessageFilters are used to determine destination(s).
    • Routing table can be changed at runtime.
    • Security can also be bridged.
    • Alternate endpoints can be specified for fail-over-safety.
    • Discovery is another new feature. It allows for location agility, dynamic / self-healing apps
    • Discovery adheres to WS-Discovery standards
    • Two mode for discovery: Ad-hoc and managed
    • Ad-hoc discovery uses broadcasts
    • Managed discovery is like UDDI with a Discovery Proxy.
  • Compile-time checked region names in Prism

    In a R&D project of mine, I’m using Prism to create a composite WPF application. I can recommend anyone writing WPF or Silverlight applications to take a look at it if you’re unfamiliair with Prism.

    One thing I dislike about it though, is that is uses strings as region names. Meaning that there’s no compile-time checking if your region names in the Shell and the names you’re using when registering the views are actually aligned.

    Here’s a small trick to get compile-time checking for your region names in Prism:

    1. Define an Enum containing the names of all known regions:

          public enum RegionName
          {
              ToolBar,
              MessageList,
              Details
          }

    2. Define a MarkupExtension for each value of the enum. This sounds like a lot of work, but with a base class like the one below, it’s no more than a few lines.

          public class BaseRegionExtension : MarkupExtension
          {
              private RegionName _regionName;
       
              public BaseRegionExtension(RegionName regionName)
              {
                  _regionName = regionName;
              }
       
              public override object ProvideValue(IServiceProvider serviceProvider)
              {
                  return _regionName.ToString();
              }
       
              public RegionName Name
              {
                  get
                  {
                      return _regionName;
                  }
                  set
                  {
                      _regionName = value;
                  }
              }


      Defining a MarkupExtension now becomes really simple:

         public class ToolBarRegionExtension : BaseRegionExtension
          {
              public ToolBarRegionExtension()
                  : base(RegionName.ToolBar)
              {
              }
          }

    3. When registering your view, just call the ToString() of the enum value you want to use:

        _regionManager.RegisterViewWithRegion(RegionName.ToolBar.ToString(), typeof(MainToolbarView));

    4. When defining regions in your Shell Xaml file, use the right MarkupExtension to reference a value in your enum:

      <ToolBarPanel>
           <ItemsControl cal:RegionManager.RegionName="{ui:ToolBarRegion}">           
           </ItemsControl>
      </ToolBarPanel>

    Have fun!

  • No regions when generating code

    Just wished I had found this option about 5 years earlier….

    image

More Posts Next page »