Thirteen Days a Week

  Home  |   Contact  |   Syndication    |   Login
  23 Posts | 0 Stories | 15 Comments | 0 Trackbacks

News

Archives

Post Categories

Monday, January 24, 2011 #

For the past month or so, I’ve been working on a Silverlight project for a client.  I’m not much of a UI developer to begin with, so getting to know Silverlight has been interesting to say that least.  There’s certainly no shortage of things I need to learn about it.  My most recent endeavor has been getting a CI build setup on our TFS server for our Silverlight applications.  I certainly didn’t think this was going to be such a challenge, but there’s doesn’t seem to be a lot of good information about how to accomplish this.  What follows is the result of much time spent searching Google, browsing various blogs and support forums that ultimately led to a successful build on our TFS server.

First, the easy part.  You’ll need to install both the Silverlight SDK as well as the Silverlight Toolkit on your build agent.  The SDK of course is needed to compile Silverlight applications and the Toolkit contains the MSBuild targets.

Next, because the Toolkit’s MSBuild targets are 32 bit, you need to configure your build to run the 32 bit version of MSBuild.  You can accomplish this by editing your build definition in Visual Studio and setting the MSBuild Platform property to X86:

Build

 

Once you’ve done this, you’ll be able to successfully build your Silverlight applications, provided you don’t have any web projects in your solution that reference your Silverlight XAPs.  If you do have a web project that references your XAPs and you run a build now, you’ll end up with an error about MSBuild not being able to copy a XAP to your web project’s ClientBin directory.  To get around this, you’ll need to manually edit the project file for the web project.  Find the line in your project file that references the XAP file.  This will be the line that begins with <Content Include=”ClientBin\….”.  Add a Condition to it, as shown below:

ProjectFile

 

Finally, add another reference to the XAP file, this is the <None /> element shown above.  So the net effect is that the XAP is ignored when the build runs on the server and not ignored when it runs on your dev desktop.


Wednesday, December 01, 2010 #

So you’ve written your business and data layer classes such that they support dependency injection via constructor parameters.  You’ve written a bunch of unit tests around them, achieved 100% code coverage and even used mocks for your dependencies.  Awesome, right?  Now you want to stand up some WCF services in front of that super unit tested business layer of yours.  Your new WCF services are going to have a dependency on those business layer objects, right?  How are you going to get around that?  Well, you could use a dependency injection container like Unity, NInject, StructureMap, etc.  But wait, now your WCF service classes have a dependency on whatever DI container you’re going to use.  That means you’re going to have to bootstrap that container in all of your unit tests for your WCF services.  What else can a developer do, right?  I mean, WCF service implementation classes have to have a default constructor, right?  It’s not long you can do constructor injection on a WCF service, right?  Wrong!  As it turns out, using some of the WCF extensibility points, it’s not too hard at all to achieve constructor injection with WCF.

WCF provides us an interface, IInstanceProvider, which can be used to control the instantiation of service instances.  This is a perfect place to put our calls into Unity or some other DI container.  An IInstanceProvider that returns service instances from a Unity container looks like this:

  1: using System;
  2: using System.Configuration;
  3: using System.Reflection;
  4: using System.ServiceModel;
  5: using System.ServiceModel.Channels;
  6: using System.ServiceModel.Dispatcher;
  7: using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
  8: using Microsoft.Practices.Unity;
  9: using Microsoft.Practices.Unity.Configuration;
 10: using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel.Unity;
 11: 
 12: namespace WcfTechTransfer.Implementation.Hosting
 13: {
 14:     public class UnityInstanceProvider : IInstanceProvider
 15:     {
 16:         private readonly Type serviceType;
 17:         private readonly IUnityContainer container;  // TODO:  Configure your Unity container
 18: 
 19:         public UnityInstanceProvider(Type serviceType)
 20:         {
 21:             this.serviceType = serviceType;
 22:         }
 23: 
 24:         #region IInstanceProvider Members
 25: 
 26:         public object GetInstance(InstanceContext instanceContext, Message message)
 27:         {
 28:             return container.Resolve(serviceType);  // This is it, the one and only call to Unity in the entire solution!
 29:         }
 30: 
 31:         public object GetInstance(InstanceContext instanceContext)
 32:         {
 33:             return GetInstance(instanceContext, null);
 34:         }
 35: 
 36:         public void ReleaseInstance(InstanceContext instanceContext, object instance)
 37:         {
 38:             if (instance is IDisposable)
 39:                 ((IDisposable)instance).Dispose();
 40:         }
 41: 
 42:         #endregion
 43:     }
 44: }
 45: 

The IInstanceProvider implementation is pretty straight forward.  We just need to provide a constructor with a parameter for the service type.  That’s what we pass into Unity to get our service instance back.

Now that you have your IInstanceProvider, you need to wire it up to each endpoint’s dispatch runtime.  This can be accomplished through a service behavior like so:

  1: using System;
  2: using System.Collections.ObjectModel;
  3: using System.Linq;
  4: using System.ServiceModel;
  5: using System.ServiceModel.Channels;
  6: using System.ServiceModel.Description;
  7: using System.ServiceModel.Dispatcher;
  8: 
  9: namespace WcfTechTransfer.Implementation.Hosting
 10: {
 11:     public class UnityInstanceProviderServiceBehavior : IServiceBehavior
 12:     {
 13:         #region IServiceBehavior Members
 14: 
 15:         public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
 16:         {
 17:         }
 18: 
 19:         public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 20:         {
 21:             serviceHostBase.ChannelDispatchers.ToList().ForEach(channelDispatcher =>
 22:             {
 23:                 ChannelDispatcher dispatcher = channelDispatcher as ChannelDispatcher;
 24: 
 25:                 if (dispatcher != null)
 26:                 {
 27:                     dispatcher.Endpoints.ToList().ForEach(endpoint =>
 28:                     {
 29:                         endpoint.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(serviceDescription.ServiceType);
 30:                     });
 31:                 }
 32:             });
 33:         }
 34: 
 35:         public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 36:         {
 37:         }
 38: 
 39:         #endregion
 40:     }
 41: }

 

Next you need to add that new service behavior to your service.  This can be done through a custom service host:

 

  1: using System;
  2: using System.ServiceModel;
  3: 
  4: namespace WcfTechTransfer.Implementation.Hosting
  5: {
  6:     public class UnityServiceHost : ServiceHost
  7:     {
  8:         public UnityServiceHost()
  9:             : base()
 10:         {
 11:         }
 12: 
 13:         public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)
 14:             : base(serviceType, baseAddresses)
 15:         {
 16:         }
 17: 
 18:         protected override void OnOpening()
 19:         {
 20:             this.Description.Behaviors.Add(new UnityInstanceProviderServiceBehavior());
 21:             base.OnOpening();
 22:         }
 23:     }
 24: }
 25: 

 

Again, pretty straight forward stuff here.  We’re just overriding the ServiceHost’s OnOpening() method and adding a new instance of our service behavior to the behaviors collection.

Finally, the last piece to the puzzle, a custom ServiceHostFactory that will return instances of your custom ServiceHost:

  1: using System;
  2: using System.ServiceModel;
  3: using System.ServiceModel.Activation;
  4: 
  5: namespace WcfTechTransfer.Implementation.Hosting
  6: {
  7:     public class UnityServiceHostFactory : ServiceHostFactory
  8:     {
  9:         protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
 10:         {
 11:             return new UnityServiceHost(serviceType, baseAddresses);
 12:         }
 13:     }
 14: }
 15: 

 

Since you have a custom ServiceHostFactory, if you’re hosting in IIS, you’ll need to reference this ServiceHostFactory in your .svc file, or, if you’re using .Net 4.0 and taking advantage of the new file-less activation, reference the ServiceHostFactory in your web.config like so:

  1: <!-- Using configuration based activation so we don't need to have .svc files -->
  2: <serviceActivations>
  3:   <add factory="WcfTechTransfer.Implementation.Hosting.UnityServiceHostFactory"
  4:        service="WcfTechTransfer.Implementation.DocumentService"
  5:        relativeAddress="DocumentService.svc" />
  6: </serviceActivations>

 

That’s all there is to it.  Now you just need to update your Unity configuration, register your WCF service contract and implementation, along with any dependencies they have.  Of course the code here uses Unity as the DI container, but there’s no reason you couldn’t do the same thing with any other container.


Saturday, October 16, 2010 #

My current project is a rewrite of a legacy system.  The client wants to be able to start leveraging the new system as we complete certain features, so this means that we need to integrate with the legacy data store.  In this case, the legacy data store is a Pervasive SQL database.  Prior to this project, my knowledge of Pervasive was limited to the fact that it was a btrieve database.  Needless to say, it’s been quite a learning experience working with Pervasive.

I was pleasantly surprised to find that Pervasive does in fact provide an ADO.Net provider.  I also found some info on Pervasive’s website that indicated they’re working an an Entity Framework provider for their next version.  We had decided to rely on Enterprise Library for our data access strategy, though Pervasive doesn’t provide an Enterprise Library provider.  EntLib does have a GenericDatabase provider, however this is limited in it’s features, specifically around the handling of parameters.  So, with that in mind, I decided to undertake writing a custom EntLib database provider for Pervasive.  As it turns out, it’s really not that daunting of a task.

You’ll need two classes, one to represent the database and one to handle registrations of the provider with EntLib.  The database class derives from Microsoft.Practices.EnterpriseLibrary.Data.Database and the registration class derives from Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseData.  Class diagrams of my Pervasive provider are below:

EntLibDbProvider

 

The bulk of the code in my PsqlDatabase class is related to handling of parameters and the parameter token used by Pervasive.  For the record, Pervasive’s parameter token is a colon.

Once you write your code, the last remaining task is to wire it up to EntLib via your configuration file.  My configuration is shown below:

Config

 

At the top of the config file, we have the usual configSections entry for using the EntLib data access block, followed by the dataConfiguration element.  This is where the magic happens.  the providerMappings element is used to map our custom database type to the registered ADO.Net provider.  Then, since Pervasive doesn’t register itself in machine.config, I have to add the Pervasive factory class in the system.data/DbProviderFactories section.

That’s all there is to it.  While my example is specific to Pervasive, it could easily be adapted to any other DBMS that has an ADO.Net provider.  If you decide to undertake creating your own provider, I would recommend reviewing the EntLib source control, specifically the classes that support EntLib’s SQL Server provider, those were really helpful to me when I was getting started.


Recently I started on a new project, with a new client.  As the project is new and the client doesn’t have an established .Net development group, we’re finding out that some things which we would often take for granted just aren’t in place.  One thing that came to light early on was the lack of a repeatable deployment process.  We’re scheduled to have a dedicated build and deploy person on our team in a few weeks, but in the meantime, I find myself in the undesirable position of having to manually deploy and configure our solution to our dev and QA environments.  Our solution consists of an ASP.Net MVC application and three WCF services.  Each of these pieces of the solution has some degree of configuration data that needs to change with each environment.  These changes include things like connection strings (database server name), WCF security settings, etc.  Without any kind of automated deployment process in place, that means I need to manually edit our configuration files each time we deploy.  Personally, anytime I need to manually edit configuration files, I manage to screw them up in some way.

So, with the prospect of another month of botched deployments in mind, I decided to see if I could find an easy solution to getting builds setup for our dev and QA environments.  One of the things I noticed early on with Visual Studio 2010 ASP.Net projects was that for some reason, I had a couple of extra configuration files:

Config file and transforms

Since part of the problem I was trying to solve related to configuration data, I decided to do some research to find out what these extra config files were and if they could help me.  I came across this blog post which provided me with the info I needed.  As it turns out, the additional files, Web.Debug.config and Web.Release.config are referred to as config transforms.  The idea is that you use web.config as your baseline, with the settings you need for your local development environment.  Then, for each solution configuration, you have a configuration trasnform file which has the changes you want to apply to your baseline configuration for that particular environment.  When you create a new solution, you have initially Debug and Release solution configurations, so that’s why you see Web.Debug.config and Web.Release.config.

In our project, since we currently have only dev and QA environments, I went ahead and added two new solution configurations, called dev and QA.  After adding the new configurations, to add the web.config transforms, you need to right click on web.config and select Add Config Transforms:

Adding config transforms

 

Your project should now look something like this:

Config file and transforms

 

Once you get your config transforms added to the project, you need to edit your transforms so that they contain the changes you’d like applied to your baseline.  There’s plenty of good info on MSDN and elsewhere online on how to do this, so I’m not going to go into this much beyond a quick example of what a simple transform might look like:

ConfigExample

The top file, web.config is my baseline and has a connection string that’s pointed to the local default SQL server instance.  Below, we see the transform for the dev environment.  Notice the connection string has a different SQL server name and has a couple of extra attributes.  xdt:Transform and xdt:Locator control how the config transform build task applies the changes to the baseline.  In this case, I’m saying that in the baseline config, replace the connectionStrings/add element that has a name attribute matching AppDataDb.

Now that we’ve built out all of the config transformations, how do we incorporate them into a build?  Visual Studio 2010 provides packaging functionality for web applications which apparently takes advantage of the config transform feature.  However for reasons I won’t go into here, I’m not able to use packages for deploying in my current project.  Instead, modified our project files to have an AfterBuild task that runs when our apps our built on our build server.  This task takes care of applying the config transforms.  To make the this process easier, I installed the PowerCommands for Visual Studio 2010 extension, since this has an option to directly edit project files.  After you install the PowerCommands and restart Visual Studio, right click on your project file and select Edit Project File:

Edit Project File

Scroll down to the bottom of your project file and find the AfterBuild event.  Depending on what kind of web project you’re working with, this may be commented out, if so, uncomment it.  We need to add a TransformXml task to the AfterBuild event, like so:

BuildFile

Note that in my case, I was working with an ASP.Net MVC project which already has a task in the AfterBuild target, the AspNetCompiler task.  In an MVC project, the AfterBuild target contains the condition “’$(MvcBuildViews)’==’true’”.  This is to enable view compilation, which is disabled by default.  You can either set the MvcBuildViews variable to true in your project file, or, as I ended up doing, move the condition from the AfterBuild target to the AspNetCompiler task.

So, with our config transforms completed and project edited, all that remains is to setup TFS build.  All I did here was to setup new builds, one for each of our configurations, setting each build to use the appropriate solution configuration (dev or QA).  I’m far from a TFS expert, so I’m sure there are better ways to handle this, but for our simple needs, this seems to be working just fine.


Thursday, September 02, 2010 #

So I'm wrapping up on a project this week and my client wanted me to walk him through a deploy to their pre-production envrionment since they won't be moving to production until some time after I'm gone.  I've been using the amazing Deployment Framework for BizTalk.  My client hadn't previously used the framework before, so I was trying to give him an overview of how the install process works as we were doing the pre-prod deployment.

We installed to the first server, then the second.  We started the deploy process on the second server and everything was looking good until the deploy process was importing the bindings.  We got the following error:

The following items could not be matched up to hosts due to name and/or
trust level mismatches:
Item: '[Receive Location Name]' Host: 'ReceiveHost'
Trust level: 'Untrusted'
You must do one of the following:
1) Create hosts with these names and trust levels and try again
2) Re-export the MSI without the binding files and have a post import script
apply a suitable binding file. (Microsoft.BizTalk.Deployment)

My client was sure that he had the hosts configured correctly and we verified that he in fact did.  After a bit of head scratching, I asked him to check adapters in the administration console and sure enough, when we looked at the MQSC adapter, it didn't have a receive handler setup for the ReceiveHost.

So, if you see the error above, remember to not only check that your hosts are configured correctly, but that you've setup adapter hanlders on the correct hosts.


Thursday, August 05, 2010 #

Yesterday I was asked to help out on another project that was trying to read some messages from an MQSeries queue.  For this particular project, they were using C# and the MQ API rather than BizTalk, because they were dealing with “grouped” messages.  Grouped messages were a completely new concept to me.  Basically, the gist of it is that you have 1 – N physical messages that make up one logical message.  Each physical message has a particular flag set to indicate it is part of a group and contains a sequence number to indicate it’s position within the group.  Additionally, the message has a Group ID property that indicates the particular logical message group it belongs to.  For example, a grouped message may look like this:

LogicalMessage

Here we have 5 separate physical messages that are all part of the same logical message.

So, the project I was asked to help out with had been having some problems reading these logical messages.  Basically, when a message that was part of a logical group was read off of a queue, it would have this garbage header data at the beginning of the message.  The screenshot below shows the content of a message dumped to the Immediate window in Visual Studio, with the garbage header highlighted in red.

image

I’m a novice when it comes to MQ and in fact my only experience has been using MQ via BizTalk, I’d never looked at the API before.  I dove in and started writing some code to see if I could read these messages and avoid the garbage data.  After considerable trial and error, I came up with the following which seems to work quite well:

  1: MQGetMessageOptions options = new MQGetMessageOptions
  2: {
  3:     Options = MQC.MQGMO_LOGICAL_ORDER | MQC.MQGMO_ALL_MSGS_AVAILABLE | MQC.MQGMO_SYNCPOINT,
  4:     MatchOptions = MQC.MQMO_NONE
  5: };
  6: 
  7: MQQueueManager qManager = new MQQueueManager("<your queue mgr>", 
  8:                                              "<your channel name>", 
  9:                                              "<your server name>");
 10: MQQueue queue = qManager.AccessQueue("<your queue name>",
 11:     MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
 12: 
 13: MQMessage message = new MQMessage
 14: {
 15:     Format = MQC.MQFMT_STRING,
 16:     Version = MQC.MQMD_VERSION_2
 17: };
 18: 
 19: using (StreamWriter writer = new StreamWriter(Guid.NewGuid().ToString() + ".txt"))
 20: {
 21:     do
 22:     {
 23:         queue.Get(message, options);
 24:         options.MatchOptions = MQC.MQMO_MATCH_GROUP_ID;
 25:         string content = message.ReadString(message.DataLength);
 26:         Console.WriteLine(content);
 27:         writer.WriteLine(content);
 28:     }
 29:     while (options.GroupStatus != MQC.MQGS_LAST_MSG_IN_GROUP);
 30: }
 31: queue.Close();
 32: qManager.Disconnect();

It seems that the key to getting rid of the garbage data at the beginning of the message was settings MQMessage.Version to MQC.MQMD_VERSION_2.

Obviously a big concern would be what happens if you’re reading a grouped message and encounter an exception before you’ve reached the last segment.  Since reading a message from a queue causes that message to be removed from the queue, this could be a real problem.  What you need is a way to read segmented messages in a transactional manner.  This is what the MQC.MQGMO_SYNCPOINT flag gets you, all calls to MQQueue.Get will be treated as a single unit of work that is either committed or rolled back.


Tuesday, July 13, 2010 #

I was doing some more work on my validation pipeline component and came across something that I thought was worth mentioning, since I've never noticed it before.

I had just added a resource file to my assembly to store my component's name, description, version, icon, etc and was just about to start writing the code to retrieve these items from the resource file using System.Resources.ResourceManager.  I can never remember how embedded resource files are named once they end up compiled in an assembly, so I fired up Reflector to have a look at the resource name.  I saw my my embedded resource where I expected it, under the Resources folder.  However I noticed something else, an internal class with the same name as my resource file and static properties for each resource it contained.

Apparently when you embed a .resx file, the compiler generates this class automatically for you.  This is probably old news to many people, especially UI developers where working with resource files is more common.  However I thought it was neat and was happy that I no longer have to remember how to use the ResourceManager when I write a pipeline component.


Monday, July 12, 2010 #

Today I started working on a pipeline component that's going to be used to validate message content.  The validation rules will be stored in BRE.  Some of the rules will rely on data from a database.  Before I started working on the pipeline component code, I wanted to get my BRE policy working. 

The rules aren't too complicated, so I didn't expect it to take long to create and test them out.  However I ran into an error I'd never seen before as soon as I tried to add some database facts to the rules.

As it turns out, the Business Rules Composer is not able to deal with schemas other than dbo.  Since none of my tables are using the dbo schema, I thought back to a couple of weeks ago when I was dealing with BRE and Oracle data.  To get around this limitation, all I did was create a temporary database with a table that matched the structure and name of the table I wanted to use in my rules.  I made sure that this new table was in the dbo schema.  Once I created the new table, I browsed to it in the Database explorer in BRC, changed the database binding to Data table/Data row and changed the Dataset name from the name of my temporary database to the name of the actual database that I'd use at runtime.

When you create your TypedDataTable and assert it into the rules engine, whether by an IFactCreator, from an orchestration or from some .Net code, you just need to make sure your DataTable and DataSet name match whatever you used when you create your rules in the BRC.  Since DataSets and DataTables are unaware of SQL Server schema names, your rules will execute just fine.


Thursday, June 17, 2010 #

I'm working on an orchestration that's retrieving some data from a Java servlet.  The servlet takes a parameter string via HTTP post and returns POX (plain old XML, no SOAP here).  I was having trouble getting a valid response from the servlet when I was sending some test messages and wanted to see what my messages were looking like as they went across the wire.  Normally I was using WCF, I'd setup message logging, but since that's obviously not an option with the HTTP adapter, my thoughts turned to Fiddler. 

A quick Google search turned up some promising results.  The posts I read all referred to using Fiddler with the SOAP adapter, but I thoght I could apply the same ideas to the HTTP adapter.  This led me to try setting the following context properties:

HttpRequestMessage(HTTP.UseProxy) = true;
HttpRequestMessage(HTTP.ProxyName) = "127.0.0.1";
HttpRequestMessage(HTTP.ProxyPort) = 8888;

I rebuilt my orch, gac'd it, bounced my host and tried submitting a test message.  Fiddler was running but I didn't see any traffic show up.  I tried fully undeploying/redeploying my application and still, no traffic in Fiddler.  I was starting to think that BizTalk was ignoring the proxy settings.  To confirm this, I closed Fiddler and submitted a test message.  Sure enough, the orch ran to completion, proving that BizTalk was ignoring the proxy settings.

I went back to my orch to see if there could be any other context proprties I needed to set.  I saw one that looked promising:  HTTP.UseHandlerProxySettings.  I set this to false, rebuilt my orch and this time when I submitted, I got an error message, which made sense, I didn't have Fiddler running.  I started up Fiddler, submitted another message and there it was, my HTTP traffic, just as I hoped.  And, I was quickly able to figure out what the problem was...I had forgotten to set HTTP.ContentType to application/x-www-form-urlencoded.


Tuesday, June 15, 2010 #

Yesterday I started working on some new functionality that I had planned to implement using the Business Rules Engine.  As I got further into it, I realized that some of my rules were going to need to reference some data that resides in an Oracle database.  I knew the Business Rules Composer supports using DataConnections and TypedDataTables, but I’d never used this functionality myself, so I wasn’t so sure how it would work with Oracle.  As it turns out, it’s very do-able, there’s just little hoop you need to jump through.

I fired up BRC and my suspicions were quickly confirmed.  BRC only recognizes SQL Server databases when it comes to editing rules.  Not letting that deter me, I decided to see if I could “trick” BRE into using Oracle data.

On my local SQL server, I created a new database and in that database, created a table that matched the schema of the table I wanted to use in the Oracle database.  I then set about creating my rules, referencing the new SQL Server database everywhere I wanted to use Oracle data.  Finally, I created a new class library and added a class that implements Microsoft.RuleEngine.IFactRetriever.  In that class, I added the necessary code to get a DataSet from the Oracle server, wrap it in a TypedDataTable and assert it into the rule engine.  It’s worth pointing out that in my IFactRetriever class, I made sure to set my DataSet name to the name of the database I’d referenced in the BRC and the DataTable’s name to the name of the table that I’d referenced in the BRC.

After gac’ing the new class library and deploying my policy, I tested and everything worked as expected.