Stupid SQL Tricks
Don't ask why I needed this, but here is a SQL function that will abbreviate a string:
create function dbo.fnAbbreviate(@source nvarchar(100))
returns nvarchar(100)beginif charindex(' ', @source) = 0
return @sourcedeclare @result nvarchar(100)
declare @i int
declare @char nvarchar(1)
set @result = ''
set @i = 0; while @i < len(@source) beginset @char = substring(@source, @i, 1)
if CONVERT(varbinary, @char) = CONVERT(varbinary, UPPER(@char))
beginset @result = @result + @char
end set @i = @i + 1 endset @result = REPLACE(@result, ' ', '')
return @result;
end
Tooling
What tools do you use? If you are reading this I bet you use some flavor of Visual Studio and some form of source control, but like most developers your tooling stops there. Why? Have you tried the various Visual Studio add-ins like ReSharper or CodeRush? How about SQL Schema diff tools like SQL Compare from Red-Gate? How about a build server like Team Build or Cruise Control?
Most developers I know would answer no to most of those questions. And honestly, I don't get it. Do you like spending time writing reams of similar code? Manually diffing schema? Figuring out why a build doesn't work in a new environment?
"Ryan, those things are too expensive. I could never get those things approved!" I call bull. Have you tried to use them? Have you seen productivity gains? If so, I bet it would be a rather easy sell to your manager. Do a simple ROI on it and you'll be amazed at how cheap most of these tools are!
If you are looking for the quick win, create a build server. Once you see how easier deployment is when you can xcopy a build to a new environment you'll be sold. Then you add in things like unit tests and longer running build verification tests and you'll be amazed. You'll start to trust your builds and rollouts to new environments won't be feared.
Here is another thing I don't get. Developers, as a whole, put up with a lot of friction before doing something about it and I'm not sure why. We spend all day writing applications that make other people's lives more productive yet we will put up with friction at almost ever step of the way.
"But that's the way it is. Writing software is hard and this is the way it's always been."
Yeah, writing software is hard, but that doesn't mean we can't write software to make it easier! There are two tools that I use everyday that you can't buy anywhere. OutWit, a Outlook add-in that creates TFS work items and IntelliPages, a small applications that lets us search our company directory/quick dialer. Both of these applications make my life easier and neither one existed until a developer on the team decided it to make time to bring it life. (I made OutWit and Ray made IntelliPages, which has been so successful internally it's now part of our standard desktop image across the organization. :))
Another tool I build/use is a simple command line app that is part of each solution and is tasked with knowing how to promote builds from one environment to the next. Get the build from the build server, put in environment, update Team Build with new environment information, that sort of thing.
My point is that as developers you need to look outside of Visual Studio more often and find tools that lower the amount of friction you deal with daily. If you are adamant that there is no way you can buy a tool, then build it. You have the power. :)
CRM 4.0 Plug-ins: Handling Entity Merges
In a recent post, CRM 4.0 Plugins, I said I would post an example of a plug-in that handles entity merges. Here is that sample! :)
public class MergeHandler : IPlugin
{public MergeHandler (string unsecureConfig, string secureConfig)
{}
public void Execute(IPluginExecutionContext context)
{ try {if (context.MessageName == "Merge" &&
context.PrimaryEntityName == "account") { string targetCrmId = ((Moniker)context.InputParameters[ParameterName.Target]).Id.ToString(); string subOrdinateId = context.InputParameters[ParameterName.SubordinateId].ToString();}
}
catch (Exception ex) {throw new InvalidPluginExecutionException(ex.Message, ex);
}
}
It's actually a lot easier than I thought. It just took me awhile to understand what values were going to be passed into Execute method of the plug-in.
Staying Technically Relevant
In the comments to my post yesterday (comments meaning the only one I got), my friend and coworker Richard Lowe pointed out that working with new technology also adds business value. I have to agree with him. Staying up to date with technology, whatever technology you use day to day, does increase business value. I took that as a given because, in my opinion, if you don't stay up to date then you become technically irrelevant and technical irrelevancy adds negative business value.
Negative business value? Yeah, negative business value. You actually becoming a liability to the company by not introducing new technology. Tool sets, frameworks and programming languages all have an expiration date (within reason. I know COBOL is still alive and kicking). When they expire, your company is now in a horrible situation (especially if that expired technology is running a core business application). Staying technically relevant removes that liability.
"So Ryan? What is technically relevant?"
Glad you asked! In my opinion there are a few things that every developer should be aware of right now. Take note that I didn't say you should be using, you should know or you should be competent in. These are things that should have at least crossed your radar so if somebody talked to you about it you would have some basis for discussion.
1.) Unit Testing
Unit testing is pretty much beyond mainstream. The tools to do unit testing are now shipping with Visual Studio.
2.) Model-View-Controller/Model-View-Presenter
These patterns have been around a long, long time (so long in fact that they have been renamed, but nobody goes by those names yet). A lot of web and windows frameworks that are coming out (or in the Java world have been out for a long time) use these patterns.
3.) Object-Relational Mapping
I don't care what tools you use. If you are a developer you owe it to yourself to at least know about O/RM. It will save you boatloads of time and money. (See: NHibernate, LINQ to Entities, LLBLGEN, iBatis, etc.)
4.) Dynamic versus Static languages
With languages like Ruby and Python being mainstream, C# adding dynamic support (Dynamic via Static) and the addition of the DLR to the .NET runtime, you need to have some understanding of why people even cared about the issue to begin with.
5.) Messaging
With the push to create isolated systems and cloud computing being "The Next Big Thing", messaging and messaging patterns are starting to get more press.
These 5 things are items that I feel that developers need to have at least heard of. I'm not claiming to be a guru in any of these (especially messaging!) and I'm sure other developers have the 5 areas that they feel everybody should be aware of. What technologies am I missing?
Business Value
(Side note: The Metra is all screwed up this morning. I'm told trains are running 20 mins late then the 7:51 pulls up going from Chicago on the to Chicago tracks. Sigh....)
Anybody that has worked with me knows that I tend to be an early adopter of technology. I love playing with Beta, Alpha, CTP and "Here is my bin folder" builds. But sometimes as an early adopter I run into trouble. Not the kind of "This build borked my machine" types of trouble, but more along the lines of "Boy this is neat but what value does it give me?" kind of trouble. If I can't find the business value in a piece of code or new technology it's nothing more than a geeky toy.
As a developer it's our job not to just write really awesome code, but to make sure that code adds value to the core business. Sometimes I struggle with that. When I'm adding some lame excel exporting feature instead of playing with Aspect Oriented Programming or when I'm fixing some edge case bug instead of doing some crazy Meta-Programming I have to remind myself that the things I am doing are increasing productivity in some other part of the business.
Sometimes though, we need to take a step back and look at those new technologies (I just came back from PDC so my brain is FILLED with new stuff). Do these new technologies increase business value? How-so? Sometimes the question is easy enough to answer (Windows will crash less), other times it's harder (Oslo will help you create textual DSLs). Whenever I'm in this position, the first thing I do is play with the technology. How long is taking me to understand it? Is it lowering the amount of code that I have to write, or just moving it around (C# to Xml configuration)? Is it lowering the amount of friction in my day-to-day life? Once I can answer those questions I can move forward and confidently promote new technologies to the business (or not as the case may be).
When you start to think of terms of business value interesting changes start to take place. When you are what feels like a death march project you start to ask around. What value are we providing? Who needs this software? What is this application going to do for them day-to-day? Are we really making work easier? The answer to those questions will either motivate you because you know you are providing value, or the questions start to float up the chain of command and project goals start to get re-aligned. There have been a few projects in my life that as stake-holders and priorities changed no one was really sure why the application was being built. Asking questions has helped to get those projects back on the right tracks.
In the end, my point is simply that when you are implementing a new feature, fixing a bug or working with brand new technology try to keep your focus on business value and not what shiny new toys you want to play with.
Streaming DVDs with Windows Media Center and XBOX 360?
One of things I've been trying to put together in my spare time is a home media center. I got an XBOX 360 and using that as my Media Center Extender my goal is to stream backups of my DVDs that I ripped to my PC that is running Windows Media Center. Unfortunately I haven't been able to come up with a solution that I find acceptable. I attempted to use Transcode360 to stream VIDEO_TS but it doesn't appear to even see the files on my machine. I then converted my VIDEO_TS files to WMV and while I can stream that, losing FF/RW is unacceptable. (Side note: Maybe FF/RW works with WMV but trying to use the XBOX controller as a remote is painful. I should probably pickup a real remote for it. That will go on my list of things to buy.)
Does anybody out there have any suggestions as to what I can do to realize my dream of a DVD jukebox? I haven't attempted straight-up MPEG-2 yet, but that is my next step. Any help would be appreciated!
Lisle to Union: Messaging
Something that has running on a background thread for awhile is "How do we implement pub/sub messaging?". One of the cons to having very silo-ed systems is how do you handle the cross-system reporting? For instance: When you want to get a list of all the customers that have more than 10 licenses and have more than 20 open tickets (totally contrived but you get the idea). That query spans 2 different domains: Billing and Support. Support knows how many tickets somebody has and Billing knows how many licenses a customer has but it's not like you can "join across systems" to get that information.
Enter the datamart! Wouldn't be great if somehow each source system could populate a central repository of data with the key pieces of data that it has authority over? Yeah that would be great! They way we have been approaching that is having snapshots of our source systems update a central warehouse every few hours. While functional, it leaves a lot to be desired. Data can be out of date, when the update is happening you might get funky results, etc. So in our quest to get realtime reporting we are looking to implement some sort of messaging sub system in our applications so we can just "write the updates to the wire" which the datamart (or any other interested system) could read.
Enter pub/sub messaging! Pub/Sub seems ideal for our needs, but how do we go about implementing it? If you ask MS the answer is "Install BizTalk!". Now I don't know about you, but I tried to install BizTalk once. The experience taught me that I don't want to do it again. It seems WAY overkill for what we are trying to do. We don't need orchestraions (or maybe we do? Problem is, to know if your problem requires it you have to implement BizTalk first and then see if it works. That doesn't sound like a very agile solution.). So if BizTalk isn't the answer, maybe using something like NServiceBus, SimpleServiceBus or MassTransit is? The problem here now is that I don't have enough information to make that decision! Like a lot of Open Source applications, all 3 suffer from poor documentation. Not on the implementation side (from the "How do I make it go?" point of view, all 3 have pretty good documentation) but on the "Is this going to solve my problem" front I can't find anything. The last option is SQL Service Broker. From a technology standpoint SQL Service Broker is interesting. Managing durable messages and conversations inside of your database. From a developer stand point, I don't think I like it. I'm back in TSQL hell, but now writing TSQL that isn't standard against a product that is probably used by only 1% of the SQL Server install base. I don't think there will be a lot of Google results when I run into problems no matter how good my Google-Fu is.
So that is where I am at today. Any advice? If my thought processes keep dead-locking trying to come up with a solution, I think I'm just going to start with NServiceBus and see what happens.
CRM 4.0 Plugins
(Lisle to Union is going to be a recurring series. I'm going to attempt to write daily my thoughts on what I'm currently working on. As to the name "Lisle to Union"? That's the train I take to get into work every morning. :))
In my current project we are consuming data out of MS CRM. Accounts and contacts to be precise. Pulling data out to display it is relatively easy using their web service apis and we are quite happy with the result. Having one silo-ed system that is in charge of a very specific domain and requesting data from that domain from very well defined end points jives with my line of thinking.
But, there is one problem with not having control over the domain. The problem is how do you find out about changes to data that you are interested in? Account name changes, contact name changes, merging of entities, etc? Luckily MS CRM has a rich plug-in model that allows you to receive messages when "interesting" things happen in the MS CRM pipeline. I say "interesting" things because you can hook into every event that you need.
When I first started looking into the MS CRM Plug-in model I first thought "This so extensible that it is useless". The amount of configuration and registration that is required is quite frightening. The awesome part is that the CRM 4 sdk has tools in it to make it super easy. They have a plugin registration tool that makes it a snap to register a plug-in for the events you are interested in and a developer tool that makes it easy to re-register any changes to your plug-in during development.
When you get a message from MS CRM you are passed a Context object that contains the entity that changed (which was the entity you said you wanted in the plug-in registration) and (here is the interesting part) the actual message that MS CRM processed. You don't get a "here is the before and after" message (which is what I was expecting). Since all of the APIs MS CRM uses are all passed on the Command Pattern, the easiest thing for them to do is pass you the command that it used. In all honesty I find this pretty slick. (and I'm happy that we are using the Command Pattern in my current app (not through-out but in places where we didn't want to play the game of "What has changed on my data model?". That is not a fun game to play.)
Unfortunately, for my first plug-in it seems I have tried to tackle one of the hardest problems in MS CRM. Entity Merging. There aren't a lot of examples out there for MS CRM and I can't find a single one for entity merging. As soon as I get it figured out I'll post more in depth on it.
PDC2008: Reflections
When I left the LA Convention Center on Thursday I was saddened. I had so much fun at PDC that I didn't want it to end. I wanted to stay there forever and learn all about all the new and interesting things coming out of MSFT and MS Research. As soon as I got back to my hotel, however, I was eager to get home. The more I thought about it, the more I realized that my brain was full and it was time to head back to home and bother my coworkers. Tell them all about the grand and wonderful things I learned. (Really, I'll just speak the wonders of Pex and C# 4.0 and M and Oslo and Azure and there I go again getting all excited!)
C# 4.0
I'm really looking forward to C# 4.0. The concept of having an "object that is statically typed to be dynamic" is really interesting. I've been looking at different dynamic languages that are out there (Ruby, Python and Boo (Okay, Boo isn't really dynamic but it pretends!)) and I've been envious of the rapid prototyping you can do since the language just "gets out of your way". I've also been enjoying some of the JavaScript work I've been doing since its also dynamic.
Dynamic typing gives you great power but (cheesy Spiderman quote) "With great power comes great responsibility". I will be the first to say that I will abuse this new feature. I mean, like really abuse it. Like apply it to every problem. Every problems solution will be "Make it dynamic!". Unfortunately that is how I learn. I have to figure out what something isn't good at to figure out what it is.
Oslo
Now here is something that I'm looking at with a keen interest. Oslo comes in three parts: M, the modeling language (that is actually comprised of 3 parts: M itself, MGrammer, and MSchema), Quadrant, the visual modeling tool and Repository, a model storage database. Of the 3 parts I'm most in interested in M and using it to create textual DSLs. I dont' know about you, but a lot of the problems I run into with applications that are heavy on the use of meta-data is being able to effectively create a user interface to model those meta-data rules. Many times the problem could be solved a lot easier using a DSL that effectively read like English. Example:
Let's say you have a ticketing system that had a customizable rules system. Every time a ticket is updated you need run through a list of rules and if the rule matches the current state of the ticket the rule event is fired (in this case it's send of an email to the people specified in the rule).
I spent some time creating a UI to administer rules for something like the above. No matter where I put checkboxes or dropdowns the UI never came together the way I wanted it. I guess the best way to put it is that it has been found lacking. What I really wanted was something like this:
When ticket status is urgent
and customer is "Big Corp"
then send email to Sales, Account Managers and ryan@ryanscompany.com
Status and Customer being properties of the ticket, Sales and Account Managers being keywords that mean the Sales people and Account Manager on the ticket.
With M, you get the ability to define exactly that. Using MGrammer you define a grammar for your language. The M runtime will then give you a simple data structure of your language and you can then process it how you see fit. Super cool stuff.
The other parts of Oslo I'm not so interested in at this moment. I'm not entirely sure I like the Repository. Well, I should rephrase that. At this point I'm not sure what it's purpose is. I don't want all of my models sitting in one database. I want each one of my applications to work with the models it cares about and (if required) publish those models and data into a larger data mart. I want silo-ed applications!
Azure
Now Azure is pretty damn cool. MS took the hard part of scaling and said "We'll do it for you". You can take your apps and put them up in MS's cloud and they will handle the scaling up and scaling out of your application automagically. (I shouldn't say completely automagically, you can't take any app and throw it up in the cloud. You have to write it with the cloud in mind). The interesting part to me is how they are going to set the pricing model. If it's geared towards the enterprise (I'm talking the 50,000+ employees enterprise) then I have a feeling that it will be of no value to me. If they have SLAs and price points that make it more approachable for the small to mid-size businesses then I'm all over it. I'm really interested to see if we can take some of our internal applications and put them in the cloud.
(Before I get hate mail: Yes I know Amazon and Google have already done it. There is more to Azure and I'll get to it in another post!)
PDC 2008: Building Textual DSLs with the "Oslo" Modeling Language
(This is going to be cool. I'm totally geeked out about Oslo and I want me some Textual DSL goodness)
((Also, I have approx 51 mins of battery left so I might have to leave early.)
- MGrammar is actually a DSL over MGraph the lowest level of M
- We will be implmenting a grammar to parse: "Contact: giodl - 555-1212"
- Inside of IntelliPad there will be 3 panes
- Left is the input
- Center is the Grammar
- Right is Output
- Errors are listed on the bottom
- Module is the top level Container for MGrammar
- Language is the top level structure "Think void main"
- token == word
- syntax == sentence
- Range expressions is ".."
- How to model whitespace?
- Explicitly model wherever we want it
- OR "interleave"
- You can use single or double quotes
- Step 1 in creating a DSL is tokenizing
- Step 2 is parsing
- Step 3 is shaping
- FYI, this is mostly a demo based presentation so it's hard to make good notes. Go watch this online.
