![]() |
|
Spaces home Claudio Lassala in Softw...PhotosProfileFriends | ![]() |
|
June 18 Material from last night's presentation at the C# SIGI think the presentation last night went pretty well, and I get some great feedback from the attendees, so that's always good. :) We’ve covered a LOT of ground: Refactoring, separation of concerns, test-driven development, Command design pattern, Action delegate, multi-threading, lambda expressions, fluent interfaces, object mappers, extension methods… Of couse, everything in small doses, just trying to raise awareness about those things. It all started with a simple WinForm app, going through the cycle of adding code to Click events on buttons, and then refactoring things out of the UI, extending it to support keyboard binding, designing a shortcut controller in a test-first style, doing more refactoring and using the Action delegate and refactoring the code to the Command pattern, then improving things a bit so to support asynchronous commands… then I’ve quickly covered object mappers and lambda expressions, and finally how to improve test code using extension methods and fluent interfaces. The source code can be downloaded here. Some people asked me how they can learn more about this stuff, and where to go find resources about it. Here are a few links to some of my previous blog entries that may help: June 11 Speaking at the Hal-PC C# SIG next weekNext week I'll be speaking at the Hal-PC C# SIG in Houston. This is something that came up last minute. Markus was booked to present there but won't be able to, so I was asked to fill in for him. The session is going to be a "C# Tips and Tricks", where I'll be covering a bunch of things. The abstract is: Claudio will cover a number of tips and techniques he has used in recent project work, including the command design pattern, Lambda expressions, extension methods, fluent interfaces, refactoring, and more. His objective is to present a few tricks that attendees can apply immediately and to inspire them to learn more about the other, more extensive topics covered. Hope to see some of you out there! :) May 27 Checking out the Source Analysis for C#I've just spent about 30 minutes checking out the recently announced Microsoft Source Analysis for C#. I definitely love the idea, but I'm not sure I'll be using it just yet. Here are some of my impressions (again, I haven't spent a lot of time on it yet)... All using directives must be placed inside of the namespaceHmm, but VS itself violates that rule on every class we create...! The property must not be placed on a single line. The opening and closing curly brackets must each be placed on their own lineHuh? But that an auto-implemented property. What would we want to split that into multiple lines?! Variable names must not start with 'm_'Hmpf, that's the standard with have here at the company... A closing curly bracket must not be preceded by a blank lineOk, this one I like. Tabs are not allowed. Use spaces insteadHuh? Thanks, but no, thanks. I've seen a lot of people complaining online about this one too. What's the problem with using tabs?? The call ... must begin with 'this.'...Ah, I like that one. This is something we've made as part of our guideline here, but couldn't use FxCop to trap for that, since the 'this.' doesn't make into the IL. Now, the problem here is that, again, the code that VS generates violates this rule all over the place, such as on the example below: I'll continue to use this tool to see if it's going to stick with me. I've tried it on a very small project, and got 246 violations; the vast majority where produced by code generated by VS. On a big project, I'd probably end up with a LOT more violations, so I'm not sure I can live with that. I believe there is a way to disable some of the rules, but haven't looked for it just yet... Anyway, I do appreciate Microsoft releasing tools like this one. Hopefully, more and more developers will start paying more attention to how they write code. Interesting training materialAs an MVP, I got offered a license to InnerWorkings training material. I've been checking out some of it, and it looks pretty interesting. I noticed they had some material on Domain-Driven Design Patterns, Enterprise Patterns, and some related topics that I'm always interested on, so I decided to try it out. There is a "Developer Interface" app, where we keep all the material purchased. Each course has a number of tasks, and each task presents the scenario to be solved, the challenges, and reference material (with links to chapter of great books such as Eric Evan's on Domain-Driven Design). The task provides a way to launch the sample project in Visual Studio. Once in VS, we get an "InnerWorkings" Tool Window that gives us quick access to the problems we need to address in the solution, and the useful links. You can either try to address the problems by yourself, or cheat and see the solution. Once you're done with it, you may click the 'Judge Project Code" button that gets added to VS to have your code analyzed to see if you've implemented things in the way that was expected. I'll certainly be checking out some of the other courses they have available (I need to catch up with some stuff such as WCF, WPF, Silverlight, LINQ to XML, etc.). May 16 Getting rid of the slow help engine in Visual StudioIt's been a few years already since the last time I've installed VS' help (MSDN) on my machines. The thing is huge, slow to come up, and it didn't use to be that good. I just got used to using a SlickRun magicword to quickly search google, which searches not only MSDN, but also other resources (often much better than MSDN) such as CodeProject, blogs, etc. Since I'm connected almost 100% of the time, why use the slow local MSDN library? Also, every once in a while a reach for the F2 key in order to start a "rename" refactoring in Visual Studio, and and up pressing F1 by mistake, and then there go 2 minutes of my life, waiting for the help window to come up (even though, again, I don't even have MSDN installed). Talking to Mike today, I remembered I used to have a little VS macro that'd search on Google the text I have selected in VS. I thought it'd be good to just re-map the F1 key to that macro. It solves to problems: allows me to quickly perform a Google search from VS, and it doesn't get me stuck waiting for the VS help window to come up if I've hit the F1 key by mistake. :) You can find an example of such macro here. In order to change the keybinding, go to Tools-Options-Keyboard, search for the "GoogleSearch" macro, and bind the F1 key to it. Matching my own record: 5 and a half years at EPS!Wow, today, May 16 2008, I'm matching my personal record at working with a company: 5 and a half years, or to be more precise, 2003 days. :) Here's a little history:
The reader have probably noticed the pattern: after the company where I've worked for over 5 years, my stay at every job was getting shorter and shorter. Eventually I've decided to go solo as an independent consultant. I had my clients, I've put together some conferences for software developers, etc. That lasted for about 8 months. I wanted to have no strings attached to any company because at that time there was a good chance EPS would be hiring me, so I wanted to make sure I could join the company at any time. And that happened in November of 2002. The rest, as they say, is history. :) May 15 Material from Tulsa School of Dev 2008 is onlineI've just uploaded the material I've presented last week at the Tulsa School of Dev 2008. The material includes slide decks and source code for my three sessions (C# 3.0, Design Patterns, and LINQ). The material can be downloaded here. Attributes on constants? Haven't thought about that...I'm currently reading this article on CodeProject where the author is creating an MVP framework (seems like a good article so far...). In there, the author applies attributes to constants of a type. I had never thought that was actually possible. I want to make sure I keep that at the back of my mind, because I think I'll be using it sometime soon. As a quick reminder, this is how that can be implemented: public class SomeClass { [Special("Some special attribute")] public const string SomeConst = "This is some constant"; } public class SpecialAttribute : Attribute { public string Foo { get; set; } public SpecialAttribute(string foo) { Foo = foo; } } This blog post has a handy method to get a list of constants defined on a type (including its baseclasses): /// <SUMMARY> /// This method will return all the constants from a particular /// type including the constants from all the base types /// </SUMMARY> /// <PARAM NAME="TYPE">type to get the constants for</PARAM> /// <RETURNS>array of FieldInfos for all the constants</RETURNS> private FieldInfo[] GetConstants(System.Type type) { ArrayList constants = new ArrayList(); FieldInfo[] fieldInfos = type.GetFields( // Gets all public and static fields BindingFlags.Public | BindingFlags.Static | // This tells it to get the fields from all base types as well BindingFlags.FlattenHierarchy); // Go through the list and only pick out the constants foreach (FieldInfo fi in fieldInfos) // IsLiteral determines if its value is written at // compile time and not changeable // IsInitOnly determine if the field can be set // in the body of the constructor // for C# a field which is readonly keyword would have both true // but a const field would have only IsLiteral equal to true if (fi.IsLiteral && !fi.IsInitOnly) constants.Add(fi); // Return an array of FieldInfos return (FieldInfo[])constants.ToArray(typeof(FieldInfo)); } And here's a little test method to show how to get the attributes out of the constants of a type: [TestMethod] public void TestMethod1() { SomeClass obj = new SomeClass(); FieldInfo[] fields = GetConstants(obj.GetType()); Assert.AreEqual(1, fields.Length); Assert.AreEqual("SomeConst", fields[0].Name); object[] attribs = fields[0].GetCustomAttributes(false); Assert.AreEqual(1, attribs.Length); SpecialAttribute special = attribs[0] as SpecialAttribute; Assert.IsNotNull(special); Assert.AreEqual("Some special attribute", special.Foo); } May 14 Vista gets on my nerves...This is just stupid: I have a folder somewhere that I've created. It's not under any security sensitive folder such as Program Files or Windows. I've copied some files into that folder. Then, I tried deleting the files. Vista asks me typical security questions, and I say "yes, just delete the damn files". Eventually it just comes back to me and tells me "access is denied". Then I try moving the files into a subfolder. It has no problems with that. Tried deleting the subfolder; no luck. Moved the files back to the original location. Next, I try opening a Command Prompt, running it as admin. I tried deleting the files there, no success either. Finally, I tried running Windows Explorer as admin, and voila, the stupid thing lets me delete the files that I HAVE CREATED!!! Oh joy. How hard should it be for me to delete a stupid file that I've created myself, sitting on a folder that I've also created, outside of any O.S. folder??? May 13 Lambda Expression and Object MappersHere's a simple implementation of an object mapper using lambda expressions that I've shown yesterday at the Tulsa School of Dev. Say we need to copy some data from one object to another. For this example my objects are a Book and an AlternateBook. The class are shown below: public class Book { public Book() { } public Book(string title, int yearPublished) { Title = title; YearPublished = yearPublished; } public string Title { get; set; } public int YearPublished { get; set; } public string AuthorFirstName { get; set; } public string AuthorLastName { get; set; } } public class AlternateBook { public string AuthorFullName { get; set; } public string Title { get; set; } } I could have a mapper that worked like this: Mapper mapper = new Mapper(book, alternateBook); mapper.AddMap("Title", "Title"); mapper.AddMap("AuthorFirstName", "AuthorFullName"); That approach would have some problems, though:
The approach using Lambda expression would look like this:
Points to note:
Now, in case you're not familiar with lambdas yet: the expression does NOT get executed when we are passing it as a parameter to the AddMapping method. At that point we are only registering the m apping; the actual execution occurs whenever we want it to. I would probably, say, at the application start, register all mappings I'm likely to use. Eventually, when I need to actually process the mapping (copying some data from one object to another), I can just call the ApplyMapping, passing in the objects involved with the mapping. For example:
The code above should produce the following results: So, how's the Mapper class implemented? Here we go: public class Mapper<TSource, TTarget> { private Collection<Action<TSource, TTarget>> m_Mappings = new Collection<Action<TSource, TTarget>>(); public Collection<Action<TSource, TTarget>> Mappings { get { return m_Mappings; } } public void AddMapping(Action<TSource, TTarget> action) { Mappings.Add(action); } public void ApplyMappingsTo(TSource source, TTarget target) { foreach (var mapping in Mappings) { mapping(source, target); } } } The class keeps a list of all the mappings within its Mappings collection, which is a collection of Action<TSource, TTarget> delegates. Both TSource and TTarget are Generic types provided to the class. The AddMaping method takes in the delegate (which we pass in as a lambda) and adds it to the Mappings collection. The ApplyMappingsTo method takes in instances for the source and target object, iterates through the Mappings collection, and invokes each mapping (don't forget it, the mapping is a delegate). That's it. Again, this is just a simple implementation. I'm pretty sure there's a lot of improvements to be done on top of this, and there's definitely something some people wrote out there around the same lines; I'll be looking for that myself in order to see how I can improve this. For instance, one thing that pops up is: what if the developer messed up and specified the mapping going from the target to the source instead? Like so:
We certainly don't want to copy the title from the Alternate Book to the Book object. I don't know of way yet to have the compiler catch that problem (any ideas?). During runtime, though, I know I could have the AddMapping method analyze the Expression Tree for the lambda it was given, and make sure that the target appears at the left side of the = sign, and the target appears at the right side. Another improvement that could be made is some optimization. For instance, itake the following code snippet:
There, the developer has used string concatenation to build up the value to be assigned to the property. The AddMapping method could have some logic that analyzes the expression tree, and if it finds something like string concatenation, it could replace that with using a StringBuilder. Of course, such optimization should only be done if we can clearly see that as being something that we really needed to squeeze better performance out of. Also, it'd be convenient to have the mapper just figure out what properties to copy from the source to the target by looking for properties that map 1:1 (that is, property name and type exist on both objects), and then let the developer only supply special mappings for properties that require transformation. I'll be doing some more research on better ways to do this kind of stuff. May 12 The Temple of the KingAfter some pretty tough weeks with a lot of work and little sleep, I spent an afternoon with my friends Milton and Lucas having some fun making some home-recording of Rainbow's Temple of the King. Nothing like having some fun to relieve some of the stress. :) Check it out: May 10 The Twitter thing is not so bad after allA few weeks ago I mentioned I had broken down and signed up for Twitter. Even though I have not yet fell for it yet, I do some of its value. It does have an obvious problem: if you're not careful, you can quickly get carried away and become and totally unproductive person. What I've been doing is to have a Twitter client open in one of my computers, and every once in a while I check out what my peers are up to (usually on short breaks or when my computer is taking to long to process something). Here are the things I've either experienced or seen that I kind of dig:
One other thing I'm not liking about it right now is the fact that I don't own an *i*Phone, I just own *a* phone; a regular Sony phone that has a tiny little web browser, which makes it *really* hard to type anything on it and post to Twitter, or to follow posts. And an iPhone isn't getting in my budget plans for the foreseen feature (there's just too many other things taking higher priority). Note: I was typing this post offline; when I got online, I saw a tweet from somebody pointing out to a post by Rick that's very similar to this one of mine. :) May 05 Tulsa's School of DevThis Saturday I'll be speaking at the Tulsa's School of Dev. I've had a great time last year, so I'm looking forward to going there again, do some presentations, attend others, and meet some old buddies there. Here are the talks I'll be delivering:
The full agenda can be found here. That's a free event, so make sure to check it out! April 22 Improving tests with Extension MethodsIn my constant search for making it easier to write tests for common things in our framework, I believe I was able to clear some things up by using extension methods. Not that this hasn't been done before, it's just that I want to document how I got to it so that I can use this post to explain the approach to other people (and maybe help somebody else learning about this). :) The scenario is: we need some clean and easy way to test validity of entities after business rules have been evaluated. One approach would be to write the test like so:
Disclaimer: nope, I don't name my tests like that. It's just that the test name isn't important here! The test would need whatever logic necessary for checking whether the entity violates a given rule, and then call an assertion for it. In order to clean that up a little bit, I created a Violates extension method on my Entity class. The extension is only meant to be used by tests. The method takes in a RuleViolationExpectation object, meant to carry the expectations for the violation of a specific rule. An assertion would be called from within that method:
The RuleViolationExpectation class looks like this:
public class RuleViolationExpectation { public Entity Entity { get; set; } public Type RuleType { get; set; } public string Message { get; set; } public ViolationLevel Level { get; set; } } The test could now look like this: [TestMethod] public void SomeTest() { CustomerEntity entity = new CustomerEntity(); entity.Violates(new RuleViolationExpectation { RuleType = typeof(CustomerNameIsValidRule), Level = ViolationLevel.Violation, Message = "Customer name must..." }); } I liked that better because I got rid of the Assert, as well as any logic that checks whether the entity violates the rule according to the expectation. Now all the developer has to do is to call the Violates method on the entity, passing in the expectation, and the framework does the rest (verification and assertion). One thing bothered me, though: the call to the method read sort of funny, kind of like "entity violatates rule violation expectation...". That didn't really express the intent well: it's not that the "entity violates a rule violation expectation".... it's more like the "entity should violate a specific rule according to the given expectation". I then rewrote the test based on how I'd like it to read for better comprehension: [TestMethod] public void SomeTest() { CustomerEntity entity = new CustomerEntity(); entity.Violates<CustomerNameIsValidRule>() .WithMessage("Customer name must blah blah blah...") .OnLevel(ViolationLevel.Violation) .Verify(); } I thought that read much better. It's more like "entity violates the CustomerNameIsValid rule, with a message like 'Customer name must blah blah blah...', and on level Violation, so Verify all of that for me". For the records, the other level option is Warning. Notice that from the call to Violates on, that's really just a long chained method call, split up into several lines just to make the code easier to read, without requiring horizontal scrolling. In order to enable such syntax, I've added one more extension method to my EntityTestExtensions class: public static RuleViolationExpectation Violates<TRule>(this Entity entity) where TRule : Rule { RuleViolationExpectation expectation = new RuleViolationExpectation(); expectation.Entity = entity; expectation.RuleType = typeof(TRule); return expectation; } The method takes the expected rule type as a generic type, instantiates the RuleViolationExpectationViolation class, associates the expectation with the entity, assigns the type of rule to the expectation, and returns it. Next, I created a RuleViolationExpectationExtensions class, and added extension methods to it, like so: public static class RuleViolationExpectationExtensions { public static RuleViolationExpectation WithMessage(this RuleViolationExpectation expectation, Each method extends the RuleViolationExpectation class, and takes in the value for one of the properties we need to assign on the expectation, we assign it, and then returns the expectation back to the caller. Got it? It's just a bunch of methods acting upon the same object. The Verify method is the one that works a period (".") at the end of the sentence, by telling the framework we're done setting up the expectation, and it's time to verify the entity against the expectation. The method just leverages the Violates method that we already have on the entity; the one that takes in the RuleViolationExpectation object. The actual implementation I've done for this in our framework is more complex and complete; the expectation class has a couple more properties that we need to check for, and it also has logic that validates the expectation so to make sure the developer has provided everything the framework needs in order to verify the entity against the expectation. If there's piece missing, the framework call an assertion and tells the developer what's missing. Also, I've created a CodeRush template that makes it REALLY easy for developer to write the code and not miss any piece. The way it works is: I put the name of my entity variable into the clipboard and then type rve (Rule Violation Expectation, but I'll probably change this), and I get this: All the developer then needs to do is to fill in the expectations, hitting enter to go through the "fields" (orange highlighted areas) in the code: Moving along with a test-first approach, I'm already thinking that the developer can write the test first for the rules evaluation verification, and then I'll write a plug-in that will read the call to "Violates..." and generate the business rule, where the dev then only needs to write the actual business logic. In case the test hasn't been created first, I can also have a plug-in that'll look at an existing business rule and then create the test based on it. I believe such approach has very little friction even for developer who aren't not entirely comfortable with TDD and test-first. What do you think? April 21 Putting LINQ queries together, one piece at a timeLast week, good pal Rod Paddock asked me an interesting question about LINQ, and I think this may be useful to others (not that the answer may not already be out there somewhere, of course...). The main scenario was that different queries had to be run depending on some options. The from and select parts of the query where pretty much the same; the parts that varied were the where and orderby ones. Here's some code to illustrate a simplified scenario:
Collection<string> months = new Collection<string> { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; IEnumerable<string> query = null; int? minNumberOfLetters = 5; if (minNumberOfLetters.HasValue) { query = from m in months where m.Length >= minNumberOfLetters select m; } else { query = from m in months where m.Length >= minNumberOfLetters select m; } bool shouldOrderByLength = true; if (shouldOrderByLength) { query = from m in months where m.Length >= minNumberOfLetters orderby m.Length select m; } foreach (var item in query) { Console.WriteLine(item); } The code should query only months whose name length is equals to or greater than minNumberOfLetter (in the sample above, that'd be 5), unless that variable holds a null, in which case all months should be returned. Also, the query should be ordered by the length of months names, in case shouldOrderByLength is true (obvioulsy, both minNumberOfLetter and shouldOrderByLenght wouldn't be hard-coded, but instead, read from user input or whatever...). The main problem with such code is that there's a lot of redundancy in the queries. What if, for instance, instead of doing select m, we wanted to do select m.ToUpper()? We'd need to make that change in multiple places. Queries can be broken up into smaller pieces. Queries don't get executed until they're iterated over, either by using in a foreach block, or calling ToList() on it (which uses a foreach internally...). That means we can tweak with them until right before the iteration happens. So, we can refactor the previous code where we first declare the part that doesn't vary in the query: var query = from m in months select m;Remember, the query above does NOT get executed just yet; we are just defining it, but not executing it (think of it as building a SQL query by concatenating strings, and eventually executing the query against the database). Then we can add the where clause to the query if appropriate: if (minNumberOfLetters.HasValue) { query = query.Where((string m) => m.Length >= minNumberOfLetters); } Same with the orderby clause: if (shouldOrderByLength) { query = query.OrderBy((string m) => m.Length); } Whenever we're done building the query, then we can iterate over it as needed. Another cool thing we can do: say we need to order the query according to some specific logic; for example, if some variable is true we want to order the query by the month's name, otherwise we want .to order it by the name's length. That could be done something like this:
Func<string, object> orderBy = null; if (orderByName) { orderBy = (string m) => m; } else { orderBy = (string m) => m.Length; } query = query.OrderBy(orderBy); Basically, we declare a Func<string, object> variable that is going to hold the expression for ordering. In the if-block we assign a lambda expression to the variable accordingly. Finally, we add the call to OrderBy to the query, passing in the expression. Here's the complete final code, in case you want to mess with it:
Collection<string> months = new Collection<string> { "January", "February", "March", April 16 Ok, ok, I'm signing up for this Twitter thing...Markus has been harassing me about to get into these Facebook and Twitter things. I've signed up for Facebook a few weeks ago (even though I don't waste my time with those little applications they have there...). Now he's been on my tail saying I have to do this Twitter thing, which I have seen people talking a lot about it, but I still can't really see why I'd want to use it. :) I've decided to give it a go... |