Issues with CWA/MVP and GlobalBank

Topics: Web Client Software Factory
Nov 16, 2007 at 8:17 PM
I'm attempting to duplicate the model used by the GlobalBank source example to use the translation service to manage mapping data objects to business objects however i keep running into issues with what appears to be caused by run time exceptions in the ObjectBuilder dll related to the usage of the InjectionContructors.

I'll try to make this as clear as possible with my usage here, but if any one would like the whole project i'd be more t han happy to send it over.

Basically i have a direct Copy of the EFT.SeviceProxies service folder from the GlobalBank solution for the generic translation classes it has. and an EmploymentService folder that contains my proxies to my web service (these work fine).

My translator class:

public class EmploymentTranslator : EntityMapperTranslator<EmploymentBiz, Employment>
{
protected override Employment BusinessToService(IEntityTranslatorService service, EmploymentBiz value)
{
Employment to = new Employment();
to.EmployerName = value.EmployerName;

return to;
}

protected override EmploymentBiz ServiceToBusiness(IEntityTranslatorService service, Employment value)
{
EmploymentBiz to = new EmploymentBiz();
to.EmployerName = value.EmployerName;

return to;
}
}

Then i have my business module

public class EmployeeHousingReferenceServiceAgent : IEmployeeHousingReferenceServiceAgent
{
private IEmploymentServiceProxy _proxy;
private IEntityTranslatorService _translator = null;

[InjectionConstructor[
public EmployeeHousingReferenceServiceAgent([ServiceDependency[ IEntityTranslatorService translator)
{
_translator = translator;
_proxy = new EmploymentServiceProxy();
}

public EmployeeHousingReferenceServiceAgent(IEntityTranslatorService translator, IEmploymentServiceProxy proxy)
{
_translator = translator;
_proxy = proxy;
}

public EmploymentBiz GetEmploymentInfo(long transactionPersonId, bool transactionPersonSpecified)
{
return translator.Translate<EmploymentBiz>(proxy.GetEmploymentInfo(transactionPersonId, transactionPersonSpecified));
}
}

The controller

public class LoanAppController
{
private IEmployeeHousingReferenceServiceAgent _ehrServiceAgent;

[InjectionConstructor[
public LoanAppController
(
[ServiceDependency[ IEmployeeHousingReferenceServiceAgent ehrServiceAgent
)
{
_ehrServiceAgent = ehrServiceAgent;
}

public EmploymentBiz GetEmploymentInfo(long transactionPersonId, bool transactionPersonSpecified)
{
return _ehrServiceAgent.GetEmploymentInfo(transactionPersonId, transactionPersonSpecified);
}

The initializer

public class LoanAppModuleInitializer : ModuleInitializer
{
private const string AuthorizationSection = "compositeWeb/authorization";

public override void Load(ICompositionContainer moduleContainer)
{
base.Load(moduleContainer);

RegisterSiteMapInformation(moduleContainer.Services.Get<ISiteMapBuilderService>(true));
AddModuleServices(moduleContainer.Services);
RegisterTranslators(moduleContainer.Services.Get<IEntityTranslatorService>(true));

}

protected virtual void RegisterTranslators(IEntityTranslatorService entityTranslatorService)
{
entityTranslatorService.RegisterEntityTranslator(new EmploymentTranslator());
}

protected virtual void AddModuleServices(IServiceCollection moduleServices)
{
moduleServices.AddNew<EmployeeHousingReferenceServiceAgent, IEmployeeHousingReferenceServiceAgent>();
}
}

When i try to run this, i get 2 run time exceptions. The first time i debug the project i'm able to break point into it up until the moduleServices.AddNew

I get this exception

Service WCSFTest.ServiceProxies.Services.IEntityTranslatorService is not available in the current context.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Microsoft.Practices.CompositeWeb.ServiceMissingException: Service WCSFTest.ServiceProxies.Services.IEntityTranslatorService is not available in the current context.

Source Error:


Line 57: protected virtual void AddModuleServices(IServiceCollection moduleServices)
Line 58: {
Line 59: moduleServices.AddNew<EmployeeHousingReferenceServiceAgent, IEmployeeHousingReferenceServiceAgent>();
Line 60: }


Stack Trace:


[ServiceMissingException: Service WCSFTest.ServiceProxies.Services.IEntityTranslatorService is not available in the current context.[
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists) +266
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists) +214
Microsoft.Practices.CompositeWeb.ServiceDependencyParameter.GetValue(IBuilderContext context) +166
Microsoft.Practices.ObjectBuilder.ConstructorPolicy.GetParameters(IBuilderContext context, Type type, String id, ConstructorInfo constructor) +143
Microsoft.Practices.ObjectBuilder.WCSFExtensions.CreationStrategy.InitializeObject(IBuilderContext context, Object existing, String id, ICreationPolicy policy) +175
Microsoft.Practices.ObjectBuilder.WCSFExtensions.CreationStrategy.BuildUpNewObject(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +480
Microsoft.Practices.ObjectBuilder.WCSFExtensions.CreationStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +66
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +63
Microsoft.Practices.ObjectBuilder.WCSFExtensions.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +423
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +63
Microsoft.Practices.ObjectBuilder.WCSFExtensions.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +423
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +63
Microsoft.Practices.ObjectBuilder.WCSFExtensions.ReflectionStrategy`1.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +423
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +63
Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +184
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) +63
Microsoft.Practices.ObjectBuilder.TypeMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) +464
Microsoft.Practices.ObjectBuilder.WCSFExtensions.WCSFBuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[[ transientPolicies) +114
Microsoft.Practices.ObjectBuilder.WCSFExtensions.WCSFBuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[[ transientPolicies) +46
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.BuildFirstTimeItem(Type typeToBuild, Type typeToRegisterAs, Object item) +67
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.Build(Type typeToBuild, Type typeToRegisterAs, Object serviceInstance) +259
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.AddNew(Type serviceType, Type registerAs) +64
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.AddNew() +127
WCSFTest.LoanApp.LoanAppModuleInitializer.AddModuleServices(IServiceCollection moduleServices) in C:\VSP\chris\WCSFTest\Modules\LoanApp\LoanAppModuleInitializer.cs:59
WCSFTest.LoanApp.LoanAppModuleInitializer.Load(ICompositionContainer moduleContainer) in C:\VSP\chris\WCSFTest\Modules\LoanApp\LoanAppModuleInitializer.cs:42
Microsoft.Practices.CompositeWeb.Services.ModuleLoaderService.Load(ICompositionContainer compositionContainer, IModuleInfo[[ modules) +621
Microsoft.Practices.CompositeWeb.WebClientApplication.LoadModules() +182
Microsoft.Practices.CompositeWeb.WebClientApplication.Application_Start(Object sender, EventArgs e) +126


If i immediately hit refresh i will get this error and not even break point into the project before i get it

Service WCSFTest.LoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current context.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Microsoft.Practices.CompositeWeb.ServiceMissingException: Service WCSFTest.LoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current context.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[ServiceMissingException: Service WCSFTest.LoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current con
Nov 28, 2007 at 2:25 PM
I found one part of the issue buried in the AppCode folder I found a snippet that was apparently intended to be moved but got left there

protected override void AddRequiredServices()
{
// TBD: Move this line to EFT or move EntityTranslatorService to CWAB and register the service
// in the Shell module.
RootContainer.Services.AddNew<EntityTranslatorService, IEntityTranslatorService>();
base.AddRequiredServices();
}

So I added

protected virtual void AddGlobalServices(IServiceCollection globalServices)
{
globalServices.AddNew<EntityTranslatorService, IEntityTranslatorService>();
}

This resolved the error about the Translator service however I still get

Service OneBrand.NonCertLoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current context.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Microsoft.Practices.CompositeWeb.ServiceMissingException: Service OneBrand.NonCertLoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current context.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


ServiceMissingException: Service OneBrand.NonCertLoanApp.Services.IEmployeeHousingReferenceServiceAgent is not available in the current context.
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists) +291
Microsoft.Practices.CompositeWeb.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists) +237
Microsoft.Practices.CompositeWeb.ServiceDependencyParameter.GetValue(IBuilderContext context) +142

I still can not step through and get an exact location this error occurs from, when i step out of the module initializer it goes directly to my custom http modules error handling that caught the error but it in no places lets me directly point what line it errors on. Of course with the stack trace it appears the error bubbles up straight from the CompositeWeb block. This is very frustrating.
Nov 28, 2007 at 3:12 PM
After some more digging I think i've concluded the exact place it's failing in the CompositeWeb block in the CreationStrategy there's the method

private static void InitializeObject(IBuilderContext context, object existing, string id, ICreationPolicy policy)
{
Type type = existing.GetType();
ConstructorInfo constructor = policy.SelectConstructor(context, type, id);

if (constructor == null)
{
if (type.IsValueType)
return;
throw new ArgumentException(Properties.Resources.NoAppropriateConstructor);
}

object[] parms = policy.GetParameters(context, type, id, constructor);
MethodBase method = (MethodBase)constructor;
ValidateMethodParameters(method, parms, existing.GetType());
method.Invoke(existing, parms);
}

The context in here seems to be what it is referring to on where the agent is not available but I can't figure out why it'd be available there in the GlobalBank solution but it does not work in my project.
Nov 28, 2007 at 4:49 PM
I had a similar problem yesterday, in so far, that I got the "Service not available in current context" exception. My error was in the MyModuleInitializer.

You could look at this routine:

protected virtual void AddModuleServices(IServiceCollection moduleServices)
{
moduleServices.AddNew<EmployeeHousingReferenceServiceAgent, IEmployeeHousingReferenceServiceAgent>();
}

and try the other contructors. Try also to use moduleServices.Add instead of AddNew and try also regitering it as a global service additionally.

Sorry that I am being so vague, but I don't have my code at hand and do not exactly remember...
Nov 28, 2007 at 7:03 PM
Edited Nov 28, 2007 at 9:23 PM
I concluded to attempt that also and switched over to

protected virtual void AddModuleServices(IServiceCollection moduleServices)
{
moduleServices.Add(typeof(IEmployeeHousingReferenceServiceAgent), new EmployeeHousingReferenceServiceAgent(moduleServices.Get<IEntityTranslatorService>(true), new EmploymentServiceProxy()));

}

However it still crashed from the injection on the Controller

public class NonCertLoanAppController
{
private IEmployeeHousingReferenceServiceAgent _ehrServiceAgent;

InjectionConstructor
public LoanAppController
(
ServiceDependency IEmployeeHousingReferenceServiceAgent ehrServiceAgent
)
{
_ehrServiceAgent = ehrServiceAgent;
}

It seems to be failing on finding the ServiceAgent after it gets added to the IServicesCollection which confuses me as I have already tested in the immediate window after I step over the lines and call Get<IEmployeeHousingReferenceServiceAgent>() and it returns the service fine however between stepping out of the module and the CompositeWeb blocks when it attempts to do the injection for the controller it can't find it and blows up.
Nov 29, 2007 at 4:36 PM
This so amazingly frustrating, I took the opposite approach. I moved my new classes into global bank solution and it works fine. Prior to this, i tried moving the source code for the blocks into my project instead of referencing the WCSF dlls and referencing those projects and still got the same crash.
Nov 29, 2007 at 8:31 PM
did you put the references in your own VS solutions web.config file (entlib, repostitory factory....)