How to map a service

Jan 31, 2011 at 7:55 AM

I have a class "TrackDataStoreService". that implements the "ITrackDataSoreService".

I try this code in the viewmodel:

ITrackDataStoreService tService;
tService = nRoute.Services.ServiceLocator.GetService<ITrackDataStoreService>();

but this code throws the fowling exception:

   "Cannot resolve resource of type easyMusic.Core.ViewServices.Contracts.ITrackDataStoreService"

That is the service implementation:

    [MapService(typeof(ITrackDataStoreService), InitializationMode = InitializationMode.OnDemand, Lifetime = InstanceLifetime.Singleton)]
    public class TrackDataStoreService : INotifyPropertyChanged, ITrackDataStoreService
    {
        private const string SERVICE_NAME = "TrackDataStoreService";

        private TrackCollection _tracks;
        public TrackCollection Tracks
        {
            get { return _tracks; }
            set
            {
                _tracks = value;
                PropertyChanged.Notify(()=>Tracks);
            }
        }
    }

what am i doing wrong?

thx

Coordinator
Jan 31, 2011 at 9:25 AM

Nothing, really - I've recreated a sample project (see http://cid-587cbdf035b4a11d.office.live.com/self.aspx/.Public/TrackDataStoreSample.zip) and it all seems to work fine. 

Though one thing I can tell you is, that specific error is a very generic error which might just be wrapping another exception - so just check the inner exception.

Cheers,
Rishi

Jan 31, 2011 at 3:00 PM

hi,

that sample you have post works fine, but my WPF application not.

I have two projects *.exe and *.core.dll.

the service is defined in the dll project, can this a reason why dose it not work?

 

thx

 

Coordinator
Jan 31, 2011 at 7:55 PM

Not really, unless the TrackDataStoreService implementation has a dependency that has not been resolved - if that is the case then on the MapService attribute declaration you specify one or more dependencies. 

All else, send me a small repo project - I can have a look.

Cheers,
Rishi 

Feb 1, 2011 at 1:18 PM
Edited Feb 1, 2011 at 1:19 PM

Did you checked the App.xaml and initialized the Application Service as followed :

    <Application.ApplicationLifetimeObjects>
        <n:nRouteApplicationService />
    </Application.ApplicationLifetimeObjects>

Feb 1, 2011 at 1:41 PM

here is the smaple project: http://cid-583c9afdfa5df548.office.live.com/self.aspx/Test/Sample.zip

thx

Coordinator
Feb 1, 2011 at 2:46 PM

The problem is actually the "lazy-loading nature" of assemblies in WPF - when the application starts, nRoute enumerate to see which assemblies are loaded in the app-domain. Now, because not a single type from the Sample.Core is used to render MainPage.xaml, WPF delays the loading of assembly which in turn means nRoute doesn't get to enumerate it.

So the solution for it is quite simple, just manually tell nRoute to map the resources in the assembly like so:

        public App()
        {
            this.Startup += new StartupEventHandler(App_Startup);
        }

        void App_Startup(object sender, StartupEventArgs e)
        {
            AssemblyMapper.MapAssembly(typeof(ISimpleService).Assembly);
        }

Or alternatively, you can use a more declarative approach to achieve the same by specifying a SiteArea and setting InitializeOnLoad to be true:

    <n:Application.ApplicationLifetimeObjects>
        <n:nRouteApplicationService>
            <n:XamlSiteMapProvider>
                <n:SiteMap>
                    <n:SiteMap.Areas>
                        <n:SiteArea Key="Core" RemoteUrl="Sample.Core.dll" InitializeOnLoad="True" />
                    </n:SiteMap.Areas>
                </n:SiteMap>
            </n:XamlSiteMapProvider>
        </n:nRouteApplicationService>
    </n:Application.ApplicationLifetimeObjects>

For the next release I'll try and put a workaround for lazily-loaded assemblies.

Cheers,
Rishi

Feb 1, 2011 at 7:26 PM

Yes it work...

thx

Coordinator
Feb 1, 2011 at 7:48 PM

Cool, and @julien1510zune thanks for your input :)

Rishi