OK, all of you Windows Workflow Foundation Experts out there. I have a question for you. (note this would go to the MSDN forums, but they are currently having login problems to Windows Live - maybe I'll repost it there later).
I'm not sure where to turn - other than just refactoring the way I'm doing things so I don't have to use the technique/design that I've put together. Which is what I'm going to do after I post this.
Here is the scoop:
I'm putting together a rather large state machine workflow using Windows Workflow Foundation. I have a custom activity that I've built that takes in an object and does some "stuff" based on the object that is passed in. Specifically, the activity calls an object that sends some notifications - this code was already written and we are just reusing it. The Custom activity simply is the wrapper to do the notifications. OK...easy enough...
To call this activity from my workflow - I need a reference to the object that has the information regarding the people to notify. In my example I have a Quote object. This quote object has some information that tells the notification which people need notified. (note that the notification object takes different types and can notify based on those different types...the Quote is simple a concrete version of those other types).
So, how do I do this - I create a dependency property in by custom activity called EntityForNotification. The type of that dependency Property is of the parent type for Quote - so I can send a Quote or other concretes into it. Then it will take and perform notifications. In my State Machine workflow, I add the custom activity and set the dependency property to a dependency property that I have set up in my state machine. In this case - the Dependency Property is called "Quote".
Here is the code for the dependency property in the state machine which needs to pass the Quote to the custom activity:
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)][BrowsableAttribute(true)]
[CategoryAttribute("Notify Task")]
public QuoteDto Quote
{
get { return (QuoteDto)GetValue(QuoteProperty); }
set { SetValue(QuoteProperty, value); }
}
// Using a DependencyProperty as the backing store for Quote. This enables animation, styling, binding, etc...
public static readonly DependencyProperty QuoteProperty = DependencyProperty.Register("Quote", typeof(QuoteDto), typeof(QuoteStates), new PropertyMetadata(null, DependencyPropertyOptions.Default, new GetValueOverride(getQuoteValueOverride), new SetValueOverride(setQuoteValueOverride)));
private object getQuoteValueOverride(DependencyObject dependencyObject)
{
QuoteDto result = null;
// Get the quote ID
Guid quoteID = ((QuoteStates)dependencyObject).QuoteID;
// Now return the quote Dto
QuoteDao quoteService = new QuoteDao();
result = quoteService.SelectByPrimaryKey(quoteID);
return result;
}
private static void setQuoteValueOverride(DependencyObject dependencyObject, object value)
{
// Not used.
}
Notice my usage of the PropertyMetaData and the delegates that override the get and set methods. I don't want to mess with the default getter and setter for the dependency properties, so (as directed by the MSDN forums) I put my custom creation of the QuoteDto into my overridden Quote getter.
The problem is, that it won't compile. I get a very long winded stack trace (pasted at the bottom of this post) that tells me that my configuration file doesn't contain the connection string for the database connection that is being used by my QuoteDao service - which, by the way, is in a completely different assembly - and works wonderfully in getting my QuoteDto objects. I can comment out the line of code that calls the .SelectByPrimaryKey(quoteID) and it compiles and runs fine. The problem is - with that commented out, there is no quote Dto that gets created and sent back - so that defeats the purpose.
Why in heaven's name is it trying to validate the Workflow activity based on a call to a completely different assembly and it's need to see a configuration file. Shouldn't they be completely decoupled??? The workflow foundation has injected a dependency that I neither asked for or even want/need - ie. I don't want to create another configuration file to make sure my workflow works. The configuration file is already in my project in another place and enables my data layer to work just fine in all of the other places in my code.
I think that is about it...if anyone has any suggestions, I'm very willing to hear them.
Thanks!!
Below is the stack trace for my error:
--------------------------------------------------------------------------
Error 1 'System.Configuration.ConfigurationErrorsException' while invoking the validator 'System.Workflow.Activities.StateActivityValidator' on activity 'QuoteStates': System.Configuration.ConfigurationErrorsException: The requested database ODS is not defined in configuration. at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.ValidateConnectionStringSettings(String name, ConnectionStringSettings connectionStringSettings) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.GetConnectionStringSettings(String name) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.NameTypeFactoryBase`1.Create(String name) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(String name) at GeneraliUsa.Everest.DataAccess.Base.DaoBase.get_Database() in C:\Projects\Everest\Source\App\Libraries\GeneraliUsa.Everest.DataAccess\Base\DaoBase.cs:line 145 at GeneraliUsa.Everest.DataAccess.SalesQuote.QuoteDaoBase.SelectByPrimaryKey(Guid quoteId) in C:\Projects\Everest\Source\App\Libraries\GeneraliUsa.Everest.DataAccess\SalesQuote\QuoteDaoBase.cs:line 170 at GeneraliUsa.Everest.Workflow.Workflows.Quote.QuoteStates.getQuoteValueOverride(DependencyObject dependencyObject) at System.Workflow.ComponentModel.DependencyObject.GetValue(DependencyProperty dependencyProperty) at System.Workflow.ComponentModel.Compiler.DependencyObjectValidator.ValidateDependencyProperty(DependencyObject dependencyObject, DependencyProperty dependencyProperty, ValidationManager manager) at System.Workflow.ComponentModel.Compiler.DependencyObjectValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.ActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.CompositeActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.Activities.StateActivityValidator.Validate(ValidationManager manager, Object obj) at System.Workflow.ComponentModel.Compiler.XomlCompilerHelper.ValidateActivity(Activity activity, WorkflowCompilerParameters parameters, WorkflowCompilerResults results) C:\Projects\Everest\Source\App\Libraries\Generali.Everest.Workflow.BusinessProcesses 1 1
0 comments:
Post a Comment