Monthly Archives: November 2014

WPF application cannot load assembly on startup

This is one of those trivial errors that trip me every time, after I step away from client development for a while.

As we all know, this error means that the CLR could not resolve the dependent assembly from its regular search path when the application started.
If you added reference to say a third part assembly, via NuGet to one of your project, you were able to design you UI using this new assembly but the application throws a similar exception upon startup, you probably forgot to add a reference to this same assembly to the main application executable project. The exception looked like this:

System.Windows.Markup.XamlParseException occurred
  HResult=-2146233087
  Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
  Source=PresentationFramework
  LineNumber=34
  LinePosition=87
  StackTrace:
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at MyApp.Analyzer.Views.ScenarioQueryView.InitializeComponent() in c:\dev\myapp\AnalysisModule\Views\ScenarioQueryView.xaml:line 1
       at MyApp.Analyzer.Views.ScenarioQueryView..ctor() in c:\dev\myapp\AnalysisModule\Views\ScenarioQueryView.xaml.cs:line 26
  InnerException: System.IO.FileNotFoundException
       HResult=-2147024894
       Message=Could not load file or assembly 'Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4' or one of its dependencies. The system cannot find the file specified.
       Source=mscorlib
       FileName=Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
       FusionLog==== Pre-bind state information ===
LOG: DisplayName = Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4
 (Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: Xceed.Wpf.Toolkit, PublicKeyToken=3e4669d2f30244f4 | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/dev/isr/dosewin/Infrastructure/Dosewin/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\dev\isr\dosewin\Infrastructure\Dosewin\bin\Debug\Isr.Dowsewin.Desktop.vshost.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/dev/myapp/Infrastructure/bin/Debug/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/dev/myapp/Infrastructure/bin/Debug/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.DLL.
LOG: Attempting download of new URL file:///C:/dev/myapp/Infrastructure/bin/Debug/Xceed.Wpf.Toolkit.EXE.
LOG: Attempting download of new URL file:///C:/dev/myapp/Infrastructure/bin/Debug/Xceed.Wpf.Toolkit/Xceed.Wpf.Toolkit.EXE.

       StackTrace:
            at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
            at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
            at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
            at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveAssembly(BamlAssembly bamlAssembly)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlTypeToType(BamlType bamlType)
            at System.Windows.Baml2006.Baml2006SchemaContext.ResolveBamlType(BamlType bamlType, Int16 typeId)
            at System.Windows.Baml2006.Baml2006SchemaContext.GetXamlType(Int16 typeId)
            at System.Windows.Baml2006.Baml2006Reader.Process_ElementStart()
            at System.Windows.Baml2006.Baml2006Reader.Process_OneBamlRecord()
            at System.Windows.Baml2006.Baml2006Reader.Process_BamlRecords()
            at System.Windows.Baml2006.Baml2006Reader.Read()
            at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
            at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       InnerException: 

For example, say you used NuGet to add reference to the Extended WPF Toolkit, into one of your class library projects, which forms one module of your main WPF application. Even though you were able to design your UI in Visual Studio using some of the controls, say DateTimePicker, provided within the toolkit, if run you application, the CLR will not be able to resolve the Xceed.Wpf.Toolkit.

To prevent this error, you always have to ensure the main entry point project, containing App.xaml.cs, also contains a reference to all of your third party libaries with their Copy Local attributes set to true. For this example, use NuGet to also add reference to Xceed.Wpf.Toolkit and you will be well on your way to creating the new big thing…..

Hopefully this is the last time this error tripe me.

AutoFac or Unity integration with Prism

When creating a WPF modular application in using Prism, your main application entry point, may need to be injected with some dependent services. Assume your main application entry page is called Shell.xaml and it needs to be constructed with an IRibbonService implementation. This dependency needs to be passed using an IoC container such as Microsoft Unity or AutoFac. This blog post provides minimal Boostrapper implementations for both IoC containers.

First Order of Business: Remove StartupUri=”Shell.xaml” in App.xaml.

This is often a stumbling block and would waste you hours of troubleshooting.

Imagine the constructor of your main Shell.xaml.cs looking like this:

  public Shell(IRibbonService ribbonService)
        {
            InitializeComponent();

            //.. do something with this ribbonService
        }

In other for this to work the following must hold true:

1. An implementation of IRibbonService has been registered with the IoC container.
2. You use the appropriate means to initialize the Shell so that its dependencies are constructed.

You implement the above steps by sub-classing an appropriate Boostrapper base class.

Using Microsoft Unity, after installing NuGet package Prism.UnityExtensions, your Boostrapper should be implemented similar to this:

 public class UBootstrapper : UnityBootstrapper
    {
        protected override void InitializeShell()
        {
            base.InitializeShell();
            // hook the main application window with your Shell
            Application.Current.MainWindow = (Window)Shell;
            Application.Current.MainWindow.Show();
        }

        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
            // ensure an implementation of IRibbonService is registered with the container
            RegisterTypeIfMissing(typeof(IRibbonService), typeof(RibbonService), true);
        }

        protected override DependencyObject CreateShell()
        {
            // here allow the ServiceLocator to create an instance of Shell, passing it dependencies
            return ServiceLocator.Current.GetInstance<Shell>();
        }            
    }

If you want to use AutoFac instead, you will need to install Prism.AutocExtension first. Then your Boostrapper implementation will look like this:

 public class UBootstrapper : AutofacBootstrapper
    {
        protected override void InitializeShell()
        {
            base.InitializeShell();
            // hook the main application window with your Shell
            Application.Current.MainWindow = (Window)Shell;
            Application.Current.MainWindow.Show();
        }

        protected override void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterType<RibbonService>().SingleInstance().As<IRibbonManager>();
            builder.RegisterType<MainWindow>().SingleInstance();
 
            base.ConfigureContainer(builder);
        }

        protected override DependencyObject CreateShell()
        {
            // here allow the ServiceLocator to create an instance of Shell, passing it dependencies
              return Container.Resolve<MainWindow>();
        }            
    }

Differences are subtle but you need to get each of those parts right.