Monday, September 25, 2006

Simple Generic Factory

Last time I presented you with simple factory pattern using dictionaries of methods and talked about Steven's (much more elegant and generic) implementation. I kept playing with Steven's code, whilst the dynamic code generation is pretty cool I kept thinking there was an easier way to accomplish the same thing; I finally came up with a much shorter version, here it is:

public static class SimpleStaticGenericFactory<TKey, TBaseType> where TBaseType : class {
public delegate TBaseType BaseTypeInvoker();
private static Dictionary<TKey, BaseTypeInvoker> methods =
new Dictionary<TKey, BaseTypeInvoker>();
public static void Add(TKey key, BaseTypeInvoker instantiatorMethod) {
if (!methods.ContainsKey(key))
methods.Add(key, instantiatorMethod);
}
public static void CreateInstance(TKey key) {
if (methods.ContainsKey(key))
methods[key]();
else //what would you like to do in this case?
throw new ArgumentException(string.Format("{0} not found", key));
}
}

that's it!, or if you prefer the non-static version:

public class SimpleGenericFactory<TKey, TBaseType> where TBaseType : class {
public delegate TBaseType BaseTypeInvoker();
private Dictionary<TKey, BaseTypeInvoker> methods =
new Dictionary<TKey, BaseTypeInvoker>();
public void Add(TKey key, BaseTypeInvoker instantiatorMethod) {
if (!methods.ContainsKey(key))
methods.Add(key, instantiatorMethod);
}
public void CreateInstance(TKey key) {
if (methods.ContainsKey(key))
methods[key]();
else //what would you like to do in this case?
throw new ArgumentException(string.Format("{0} not found", key));
}
}

We *don't really need* the CreateInstance method there, we could call the method directly if the dictionary was public, but it wouldn't be good to give them access to the dictionary. Using the reports from our last example, we could use it like:

SimpleStaticGenericFactory<string, BaseReport>.Add("report1", delegate() { return new Report1(); });
SimpleStaticGenericFactory<string, BaseReport>.Add("report2", delegate() { return new Report2(); });
SimpleStaticGenericFactory<string, BaseReport>.CreateInstance("report1");

or using the non-static version:

SimpleGenericFactory<string, BaseReport> reports1 = 
new SimpleGenericFactory<string, BaseReport>();
reports1.Add("report1", delegate() { return new Report1(); });
reports1.Add("report2", delegate() { return new Report2(); });
reports1.CreateInstance("report1");

nice and simple, I'll put an example together for a plug-in model using this factory


kick it on DotNetKicks.com

Saturday, September 23, 2006

Simple factory pattern using Dictionaries of methods

I have been talking about arrays of methods, dictionaries of methods, how both techniques are very similar in implementation, when you can use either one, and a practical implementation of the simple factory pattern using arrays of methods. Today I'll show you the implementation of the simple factory pattern using dictionaries of methods and then we'll move into more interesting things, Steven posted an implementation of the same pattern that leaves my implementation in the dust, I'm still posting my code here as another example of how you can use dictionaries of methods. 

using ReportCreatorDictionary = Dictionary<string, ReportCreatorDelegate>;
//this is our base product
abstract class BaseReport {
public BaseReport() {
Console.WriteLine("Base Report Created");
}
public abstract void Execute();
}//product 1
class Report1 : BaseReport {
public Report1():base() {
Console.WriteLine("Report1 created");
}
public override void Execute() {
Console.WriteLine("Report1");
}
}//product 2
class Report2 : BaseReport {
public Report2():base() {
Console.WriteLine("Report2 created");
}
public override void Execute() {
Console.WriteLine("Report2");
}
}

delegate BaseReport ReportCreatorDelegate();
//this is the actual factory
class ReportGenerator {

static BaseReport CreateReport1() {
return new Report1();
}

static BaseReport CreateReport2() {
return new Report2();
}

static ReportCreatorDictionary reports;

static ReportGenerator() {
reports = new ReportCreatorDictionary();
reports.Add("Report1", new ReportCreatorDelegate(CreateReport1));
reports.Add("Report2", new ReportCreatorDelegate(CreateReport2));
}

public static BaseReport Execute(string reportType) {
return reports[reportType]();
}
}

and the way to use it:

BaseReport report1 = ReportGenerator.Execute("Report1");
report1.Execute();

BaseReport report2 = ReportGenerator.Execute("Report2");
report2.Execute();

of course the choice of the report to be executed can come from anywhere (drop down list, link on a web page, configuration, etc)


The problem with this implementation, as Steven points out, is that you have to change the factory every time you add a new product to the factory and is not flexible enough to create (for example) a plug-in model, because all the types are required to be known at compile time; and if you need a factory for another product you have write a new factory (duh!, you might think). Steve's implementation is a Generic factory that can be re-used with any other types (products); no need to write the factory, you just add the products to it and is ready to be used, go check it out, is definitely worth reading.


Steve's code has given me another idea, I'll see if it actually works the way I have pictured it and then blog about it


for now here's the code for the dictionaries of methods and this example of the factory; as always, play with it, learn from it, improve it


kick it on DotNetKicks.com

Friday, September 22, 2006

IE "Blog this" integrates with Live Writer

a few days ago I was reading on Geoff's blog that he became a Live Writer Junky and I commented that I just missed the "blog this" and "send to web snippets" features from Flock; well, Geoff wrote an extension for IE that adds this functionality and allows you to blog in Live Writer kinda the way Flock does it, but of course you get all the niceties (is this a word?) of Live Writer

that also led me to learn something new, I didn't know it was so easy to create an extension for IE, just using javascript and some registry keys, check it out

Thursday, September 21, 2006

Basic good practices

I've been kinda busy lately doing a lot of refactoring, I hope to be back to post about C# interesting things like generics and patterns soon

meanwhile, I've been catching up reading my blogs, I got to this post from Jeremy Miller, "The Will to be good", there are a few points that I have always taken to heart:

  1. Don't tolerate bad code. 
  2. Don't write code on top of bad code.
  3. Fix a broken build
  4. The "design hat" never comes off.
  5. Does quality even matter?. Absolutely

For me these things are more basic than even testing, if you follow these simple guidelines your tests will run smoothly

I don't tolerate bad code and/or developers who write sloppy code, I don't even tolerate to have warnings in my code

You will always find people in some teams who are not very good at these basic things (and I'm not talking about my current team, in case they are reading this), and you have to learn how to deal with these people, if you are the team lead that's part of your job, you have to show them better techniques, even though I know is hard, specially if you are younger than them; if you are not the team lead it gets even harder, but all you can do is be an example, if you follow those practices you will be a better developer than one that doesn't, and people will see that and start listening to you at some point.

Managers may get scared when they hear you are refactoring like mad, but that shouldn't stop you from doing so (you might even have to do it after work hours), after all you are just making life easier for you and your team

Friday, September 15, 2006

Wasabi on Wails

People rewriting their stuff in this new cool framework, what are you waiting for?

JJJ

smart-er Rootkits in Codecs

I'm afraid this is going to bite a LOT of people

You’re surfing the web, and you find a video that you really want to watch, (no, not one of “those” videos… well, not necessarily anyway), but it says you have to install a codec. Codec stands for compressor/ decompressor and is used to make otherwise huge video files into a more manageable size. You install the codec, and maybe you see the video, and maybe you don’t, but guess what? You’ve been rootkitted! Now, on one level, that’s just the classic bait and switch/ trojan horse scenario, but the _details_ are quite interesting.

be careful out there

Wednesday, September 13, 2006

photoshop amusement

truly amazing what some people can do with Photoshop (click on the picture to see a bunch more)


Tuesday, September 12, 2006

Incremental search in Internet Explorer "a la Firefox"

In case you haven't seen this yet (and if you use Internet Explorer for whatever reason), you can now have the (very requested) feature of finding text as you type in IE, almost like in Firefox

Find as you type

Dictionaries of methods in C#

This article is a follow up of my previous article arrays of methods in C#, as noted by some of the commenters, it is possible to implement this technique using dictionaries, Steven even (Steven even... kinda funny... anyway, where was I? oh ok) posted a comment with the full implementation of my code using dictionaries, I just wanted to hightlight some of the differences and perhaps give you a hint on when to use either one (although it should be obvious, but I've learnt that there is no such thing as obvious)

Since the dictionaries implement a <Key, Value> way of storing stuff, you can store an int or a string, or any other type as the key as long as you don't have duplicated entries, and on the value you can store the pointer to the method you want to execute, when using arrays you are limited to use types that can be converted to integers for the index, with dictionaries you could use other types as the index.

let's see the last example and how it changes, the changes -as you will see- are pretty minimal to switch between the two

- The delegate declaration doesn't change

- now instead of an array, we have a dictionary, it looks something like this:

Dictionary<int, AddStringDelegate> addStringMethods;

- The methods declaration stay the same


- Adding the methods to our dictionary is just a little bit different:

addStringMethods = new Dictionary<int, AddStringDelegate>(4);
addStringMethods.Add((int)StringType.Type1, new AddStringDelegate(AddStringType1));
addStringMethods.Add((int)StringType.Type2, new AddStringDelegate(AddStringType2));
addStringMethods.Add((int)StringType.Type3, new AddStringDelegate(AddStringType3));
addStringMethods.Add((int)StringType.Type4, new AddStringDelegate(AddStringType4));

- The implementation to use the methods remains exactly the same

public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}

We're done! so we just had to change a couple places and we are now using dictionaries of methods instead of arrays.


So when do I use dictionaries over arrays? basically, when you need it, arrays are a lot more simple and lightweight, dictionaries add weight but give you a lot more flexibility, for example if you want to use a string as the index to access your method, then the dictionary is the way to go; dictionaries also allow you to add/remove items from it, I don't know that it would be a good idea to apply that in this case, but you can do it. If you can get an integer index I would use the array instead, you don't really need the dictionary in that case.


If no one (out of my 3 readers J) beats me to it, I'll run some tests using both approaches and see if there is any relevant difference in speed and I'll post the results here. If you do the tests, and you blog about it, and I find out, I'll put a link here just as a follow up to this


Here's the full code, play with it, break it, expand it, make it better

class FileGeneratorBase {

Dictionary<int, AddStringDelegate> addStringMethods;

public FileGeneratorBase() {
addStringMethods = new Dictionary<int, AddStringDelegate>(4);
addStringMethods.Add((int)StringType.Type1, new AddStringDelegate(AddStringType1));
addStringMethods.Add((int)StringType.Type2, new AddStringDelegate(AddStringType2));
addStringMethods.Add((int)StringType.Type3, new AddStringDelegate(AddStringType3));
addStringMethods.Add((int)StringType.Type4, new AddStringDelegate(AddStringType4));
}

public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}
void AddStringType1(string someValue) {
OutputText(string.Format("String Type 1: {0}", someValue));
}
void AddStringType2(string someValue) {
OutputText(string.Format("String Type 2: {0}", someValue));
}
void AddStringType3(string someValue) {
OutputText(string.Format("String Type 3: {0}", someValue));
}
void AddStringType4(string someValue) {
OutputText(string.Format("String Type 4: {0}", someValue));
}
void OutputText(string someValue) {
Console.WriteLine(someValue);
}
}

class Program {
static void Main(string[] args) {
//*** Arrays of methods demo
FileGeneratorBase fg = new FileGeneratorBase();
fg.AddString("some value", StringType.Type1);
fg.AddString("some other value", StringType.Type2);
fg.AddString("one last value", StringType.Type3);
fg.AddString("testing out of bounds", StringType.Type4);
Console.ReadLine();
}
}

on my next article I'll show you the implementation of this technique applied to the simple factory pattern just to close the loop.

Friday, September 08, 2006

Simple factory pattern made simpler

A Simple Factory pattern returns an instance of one of several possible classes depending on the data provided to it.

Last week I talked about a technique that allows you to reduce (and effectively reuse) code when you have a pattern of 2..n values, where for each value you want to execute a different method with the same signature

if (someValue == SomeEnum.Type1)
Method1("value 1");
else if (someValue == SomeEnum.Type2)
Method2("value 2");
else if (someValue == SomeEnum.Type2)
Method3("value 3");

while the method is valuable by itself, there is a pattern where it fits perfectly, this is the simple factory method; let's start with a reports example.

Suppose we have a Base Report class, and two implementations of it:

abstract class BaseReport {
public BaseReport() {
Console.WriteLine("Base Report Created");
}
public abstract void Execute();
}
class Report1 : BaseReport {
public Report1():base() {
Console.WriteLine("Report1 created");
}
public override void Execute() {
Console.WriteLine("Report1");
}
}
class Report2 : BaseReport {
public Report2():base() {
Console.WriteLine("Report2 created");
}
public override void Execute() {
Console.WriteLine("Report2");
}
}

enum ReportType {
Report1,
Report2
}
To use the arrays of methods, we have to declare our delegate to instantiate the reports:
delegate BaseReport ReportCreatorDelegate();
Then we have our factory class that contains:

  • An array of methods

  • a method to instantiate each report

  • The method to execute the requested report, depending on the parameters
class ReportGenerator {
static BaseReport CreateReport1() {
return new Report1();
}
static BaseReport CreateReport2() {
return new Report2();
}
static ReportCreatorDelegate[] reports;
static ReportGenerator() {
reports = new ReportCreatorDelegate[2];
reports[0] = new ReportCreatorDelegate(CreateReport1);
reports[1] = new ReportCreatorDelegate(CreateReport2);
}
public static BaseReport Execute(ReportType reportType) {
return reports[(int)reportType]();
}
}

Then here's how we use this code:

BaseReport report1 = ReportGenerator.Execute(ReportType.Report1);
report1.Execute();

BaseReport report2 = ReportGenerator.Execute(ReportType.Report2);
report2.Execute();
Console.ReadLine();
Update: Pablo commented "the fact that calling the factory with the type you want to create is kinda the same as creating it yourself", it is true, I could've just created an instance directly my self there, but this was just a bad example from my part, that value could come from a drop down select list, from a configuration file, etc, I just did a bad job showing you how you could use the code.

This particular example is very light weight and works great to implement this simple pattern, but it has the limitation that it works only for values that can be converted to integerAyende and Steven pointed out that the same technique can be implemented using Dictionaries, this would allow us to have other types as the index of our collection of methodsOn my next posts I'll show you this technique, using Dictionaries of methods

You can find the full source code for this and my previous example here

How to install multiple personalities of Turbo Explorer

Andy has created a program that allows you to install multiple personalities of the Turbo Explorer products (since by default you can only install one)

The steps, according to Andy are really simple:

How to install
==============
1. Install the first Turbo Explorer personality with the installer
that is included in the Turbo Explorer download.
2. Extract the next Turbo Explorer personality installer to a directory
of you choice.
3. Start the TurboMerger.exe and select the directory where you have
extracted the next Turbo Explorer personality installer. Press the
"Install" button. In the InstallShield installer do not change the
directories. Doing this will destroy the Turbo Explorer installation.
4. Proceed with step 2. until you have installed all personalities you
want.

if you are one of the people who downloaded these products, this is definitely a must have

where Delphi stands right now

Daniel Wichnewski just posted the number of downloads for the turbo explorer products, a few thousand downloads, these are the most significant numbers:

turbocpp.exe: 464
turbocpp_de.exe: 348

turbocsharp.exe: 232
turbocsharp_de.exe: 226

turbodelphi.exe: 766
turbodelphi_de.exe: 851

turbodelphi4net.exe: 200
turbodelphi4net_de.exe: 266

Delphi for .NET doesn't seem to be very popular

Wednesday, September 06, 2006

XML Notepad

going through my blogs I found this little tool

XML Notepad 2006 provides a simple intuitive user interface for browsing and editing XML documents.

definitely one more to have in the toolbox

Finding great developers

Joel talks about his experiences hiring developers and how difficult it is to get the great ones, his main point is that the great developers are already taken and that most of the resumes you get are from the pretty bad developers 

The great software developers, indeed, the best people in every field, are quite simply never on the market.

The average great software developer will apply for, total, maybe, four jobs in their entire career.

I guess I'm on a good path, I'm still on my first job J

I've had many discussions with co-workers about this same topic, while I pretty much agree with everything Joel says on this post, there's some people who think that is not that hard to get good developers

I'm of the idea that from a generation of (so-called) computer scientists you get one or two good developers (the great ones are a lot more rare than that)

Joel then goes on describing how you could get some of those great developers:

  • Go to the mountain
  • Internships
  • Build your own community*
  • That pretty much leaves out medium and small companies, there's no way they could afford to do things like that

    He closes the article by listing some problems you might face if you use employee referrals

    Unfortunately for me I haven't personally met anyone that I consider a great developer, I wish I had because I would've learnt so much more and faster; I have met very few that I consider good developers, but I guess is all up to your own standards, it's about how passionate you are about developing, it's about how good you are

    Ayende pictures developing as an art, that describes it fairly well for me, I believe a talent is required, and as such, you are born with it, sure you can learn it, but you won't be anywhere near as good as someone who has the talent

    This blog post doesn't make justice to Joel's article, Joel has been on the business for quite a while, he does know a thing or two about developers J, go check his article

    The Turbos are back

    Not the latest and greatest news, I'm just catching up with my blogs; the guys at "DevCo" have been working really hard and came out with free versions of the IDEs for Delphi, C++ and C#

    What does it have for you? If you are using VS for .NET 1.x, not much, if you are using .NET 2.0 there's (almost) nothing here for you, but if you still need Win32 applications, these are by far the best IDEs to create native win32 applications

     

    Please Note! Only one Turbo Explorer edition can be installed per machine, so be sure to download and install the one that's best for you!

    It's free and is the best, you can't go wrong with that

    The download page is here

    Wednesday, August 30, 2006

    Arrays of methods in C#

    How many times have you written code that goes something like this:

    if (someValue == SomeEnum.Type1)
    Method1("value 1");
    else if (someValue == SomeEnum.Type2)
    Method2("value 2");
    else if (someValue == SomeEnum.Type2)
    Method3("value 3");

    maybe you used a switch statement to accomplish the same kind of thing.


    You can see the pattern there, Method1, Method2 and Method3 all have the same signature and they get executed when the value Type1, Type2 or Type3 is passed. Wouldn't be nice if we could reduce that to a single line?


    That's exactly what arrays of methods can do for you, let's see an example, before we can use them we need to set them up


    Since all the methods share the same signature it means we can use a delegate to represent all of the methods.

    delegate void AddStringDelegate(string someValue);

    Now we can declare an array of delegates:

    AddStringDelegate[] addStringMethods;

    We will use an enumeration to access the items of the array:

    enum StringType {
    Type1,
    Type2,
    Type3,
    Type4
    }

    Then we need the actual methods declaration:

    void AddStringType1(string someValue) {
    OutputText(string.Format("String Type 1: {0}", someValue));
    }
    void AddStringType2(string someValue) {
    OutputText(string.Format("String Type 2: {0}", someValue));
    }
    void AddStringType3(string someValue) {
    OutputText(string.Format("String Type 3: {0}", someValue));
    }

    finally, on the constructor of our class, we assign the methods to the array to get our array of methods:

    addStringMethods = new AddStringDelegate[3];
    addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
    addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
    addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);

    It's ready to be used, let's see what the implementation looks like:

    public void AddString(string someValue, StringType stringType) {
    addStringMethods[(int)stringType](someValue);
    }

    As you can see we can access the required method by converting the enumeration to an int type, our code was just reduced to 1 line; passing the desired enum type gets to our method in one shot


    I'll let you decide when you want to use this technique, I wouldn't recommend using it in a small class that gets instantiated and thrown very fast and often, but in some cases it might even be useful there


    I think it would be specially useful if we had this kind of pattern inside a singleton class where the class could potentially live a lot longer, you could do all the work to initialize your array of methods and be able to re-use it effectively


    Here's the full code for this example, on my next post I'll show you how you could use this technique to implement some kind of factory pattern or what is sometimes referred to as simple factory pattern

    class FileGeneratorBase {
    delegate void AddStringDelegate(string someValue);

    AddStringDelegate[] addStringMethods;

    public FileGeneratorBase() {
    addStringMethods = new AddStringDelegate[4];
    addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
    addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
    addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);
    addStringMethods[(int)StringType.Type4] = new AddStringDelegate(AddStringType4);
    }

    public void AddString(string someValue, StringType stringType) {
    addStringMethods[(int)stringType](someValue);
    }
    void AddStringType1(string someValue) {
    OutputText(string.Format("String Type 1: {0}", someValue));
    }
    void AddStringType2(string someValue) {
    OutputText(string.Format("String Type 2: {0}", someValue));
    }
    void AddStringType3(string someValue) {
    OutputText(string.Format("String Type 3: {0}", someValue));
    }
    void AddStringType4(string someValue) {
    OutputText(string.Format("String Type 4: {0}", someValue));
    }
    void OutputText(string someValue) {
    Console.WriteLine(someValue);
    }
    }

    class Program {
    static void Main(string[] args) {
    FileGeneratorBase fg = new FileGeneratorBase();
    fg.AddString("some value", StringType.Type1);
    fg.AddString("some other value", StringType.Type2);
    fg.AddString("one last value", StringType.Type3);
    fg.AddString("testing out of bounds", StringType.Type4);
    Console.ReadLine();
    }
    }

    updated: To initialize the array using the same enum instead of hardcoded values of 0..4

    Monday, August 28, 2006

    Hiding generics complexity part II

    on previous articles I talked about complex generic types

    Multidimensional generics

    and how to make those types more readable by using aliases

    Hiding generics complexity

        using System.Collections.Generic;
    using FilesList = List<string>;
    using FoldersWithFiles = Dictionary<string, List<string>>;
    using ComputersWithFiles = Dictionary<string, Dictionary<string, List<string>>>;

    Here is another technique to accomplish readable code while still using generics.


    We can subclass the generics in this way:

        class FilesList2 : List<string> { }
    class FoldersWithFiles2 : Dictionary<string, List<string>> { };
    class ComputerFiles2 : Dictionary<string, Dictionary<string, List<string>>> { }
    class ComputersWithFiles2 : Dictionary<string, Dictionary<string, List<string>>> { }

    The code to use them is pretty much the same as when we were using aliased generics, but there is a little "problem", KeyValuePair is a struct and as such it doesn't support inheritance, which means we can't apply this technique to this type, so we can combine aliased types for the KeyValuePair and sub-classing for the rest


    This brings us to another point, when we have code like this:

    Console.WriteLine("List of Directories with files");
    FoldersWithFiles2 foldersWithFiles = GetFoldersWithFiles();
    foreach (FoldersWithFilesPair kv in foldersWithFiles) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv.Key));
    ListFiles((FilesList2)kv.Value);
    }

    If we want to use FoldersWithFilesPair.Value as a FilesList2 type we have to typecast it, this is because FilesList2 is a new type and FoldersWithFilesPair.Value is a List<string>; remember that C# is a type-safe language.


    Subclassing the generic types in this way can give you more benefits than simply more readable code, as any other class they can implement methods so you can assign them more specific tasks/methods that reflect more accurately their responsibility


    There is a big difference betwee using aliased generics and subclassed generics, aliased types are the exact same type, just with a different name, subclassed generics are a new name and a new type.


    This is it for now, you now have a new tool in your toolbox, as with everything else in life, don't abuse it!


    Hope to see some code where people are using these techniques


    as promissed, here is the full source code, the code is free as in LPGL

    Sunday, August 27, 2006

    the church of... Google?

    We at The Church Of Google believe a convincing argument can be made stating that the search engine Google is the closest mankind has ever come to experiencing an actual Deity. It is the ultimate bridge between people and information.

     

    Thou shalt have no other Search Engine before me, neither Yahoo nor Lycos, AltaVista nor Metacrawler. Thou shalt worship only me, and come to Google only for answers.

    ..way too much free time on their hands

    what!? you are going to join?

    Friday, August 25, 2006

    The programmer's Bill of Rights

    I'm all up for this:

    I propose we adopt a Programmer's Bill of Rights, protecting the rights of programmers by preventing companies from denying them the fundamentals they need to be successful.

    ...is just weird that the link is 666...

    finally {} is not a good place to commit your transactions

    I just fixed some code (not written by me!) that went something like this:

    transaction = connection.BeginTransaction();
    try {
    try
    {
    //***.... database operations here...
    } finally {
    transaction.Commit();
    }
    } catch {
    transaction.RollBack();
    }

    First of all, there is a bug there, if an exception is ever raised, it will raise a new exception because it cannot rollback a transaction that was committed (the message will not be that clear, but that's what it means, the exception says something about unable to complete the operation due to the current state of the object), and you'll lose the original exception that you got


    Second, it's just wrong, it defeats the purpose of using a transaction, is like you are saying


    //*** delete some records


    //*** update some records


    //*** some db operation that caused some exception


    //*** finally, commit what I had done so far


    leaving your data in an unknown state because you commited all the operations up until it failed


    hint: always use "using" for any DB related stuff (connections, commands, transactions, etc)

    Tuesday, August 22, 2006

    Hiding generics complexity

    On my last post I showed you some wicked use of generics, Ayende says he can't read code like that and provided an alternative; I agree with him, it is very ugly code, but there is hope!

    here's the equivalente code for the first section (note that I'm still using generics, even if it doesn't look like it), where we wanted to store a list of file names:

    FilesList filesList = GetFilesList();
    ListFiles(filesList);
    Then we have the bidimensional generic, to store folder name and the files in it:
    FoldersWithFiles foldersWithFiles = GetFoldersWithFiles();
    foreach (FoldersWithFilesPair kv in foldersWithFiles) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv.Key));
    ListFiles((FilesList)kv.Value);
    }

    And finally where we store computer names, with the folders, with the files in it:

    ComputerFiles computerFiles = GetComputerFiles();
    foreach (ComputersWithFoldersPair kv in computerFiles) {
    Console.WriteLine(string.Format("Computer: [{0}]", kv.Key));
    foreach (FoldersWithFilesPair kv1 in kv.Value) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv1.Key));
    ListFiles((FilesList)kv1.Value);
    }
    }
    And my last example would now look like this:
    ComputerFiles computerFiles = new ComputerFiles();
    instead of this:
    Dictionary<string, Dictionary<string, List<string>>> ComputerFiles = 
    new Dictionary<string, Dictionary<string, List<string>>>();

    Now, if the code is equivalente and I'm still using generics, what did I do?


    I am using aliased generics (yup, invented here too J) which give me friendly names, instead of the ugly multidimensional generics syntax

    Here's the aliases declaration:
    using System.Collections.Generic;
    using FoldersWithFilesPair = KeyValuePair<string, List<string>>;
    using ComputersWithFoldersPair = KeyValuePair<string, Dictionary<string, List<string>>>;

    using FilesList = List<string>;
    using FoldersWithFiles = Dictionary<string, List<string>>;
    using ComputerFiles = Dictionary<string, Dictionary<string, List<string>>>;

    The best of both worlds, you can use complex generic data structures and keep your code readable.


    You put all the uglyness in a simple place, and you are able to use friendly names which look like normal classes, plus you get more extensibility because you could change the signature of the aliased generics without breaking the code.


    On my next post I'll show you another technique to accomplish the same thing, and some gotchas, then I'll put the full source code in a zip file so you can download it.

    Blogging since 1969

     some people have just been blogging for too long

    (oh yeah, and I wanted to test the Live Writer image uploading capabilities...)

    Monday, August 21, 2006

    C# multidimensional generics

    You can think of Generics as Arrays on steroids or Collections on steroids or a combination of both, they offer an extensible list of items with type safety; or as MSDN puts it:

    Generics allow you to define type-safe data structures, without committing to actual data types.

    One thing that I haven't seen much is how you can use multidimensional generics (yup, invented here J), let me explain what I mean

    let's say we wanted to store a list of file names, we could do something like:




    List<string> filesList = GetFilesList();
    ListFiles(filesList);


    now, we want a list of directories with the files in them, we could use a bidimensional generic type to keep the directory name on a dictionary key and the list of files on the dictionary value:


    Dictionary<string, List<string>> foldersWithFiles = GetFoldersWithFiles();
    foreach (KeyValuePair<string, List<string>> kv in foldersWithFiles) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv.Key));
    ListFiles(kv.Value);
    }


    finally, let's say we want a list of computers, with folders that contain files, we can use a multidimensional generic type that has the computer name on a dictionary key, and the folders with files on another dictionary stored as the key:




    Dictionary<string, Dictionary<string, List<string>>> ComputerFiles = GetComputerFiles();
    foreach (KeyValuePair<string, Dictionary<string, List<string>>> kv in ComputerFiles) {
    Console.WriteLine(string.Format("Computer: [{0}]", kv.Key));
    foreach (KeyValuePair<string, List<string>> kv1 in kv.Value) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv1.Key));
    ListFiles(kv1.Value);
    }
    }


    For the sake of completeness here's the ListFiles function, just so you can see some cool use of generics combined with anonymous delegates:


    static void ListFiles(List<string> filesList) {
    filesList.ForEach(new Action<string>(delegate(string s) { Console.WriteLine(string.Format(" {0}", s)); }));
    }


    As you can see, with generics we can create some complex type-safe data structures, however, as always, some people will complain that multidimensional generics become very cryptic;

    and you can see it if you did something like:



    Dictionary<string, Dictionary<string, List<string>>> ComputerFiles = new Dictionary<string, Dictionary<string, List<string>>>();

    in my next post I'll show you a couple techniques you can use to hide the generics complexity while keeping all of their benefits

    Tuesday, August 15, 2006

    RegisterChannel is obsolete, use RegisterChannel instead

    I got this error:

    Warning 6 'System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(System.Runtime.Remoting.Channels.IChannel)' is obsolete: 'Use System.Runtime.Remoting.ChannelServices.RegisterChannel(IChannel chnl, bool ensureSecurity) instead.'

    It threw me off for a little while because System.Runtime.Remoting.ChannelServices.RegisterChannel doesnt' really exist

    the problem there was that they just missed the .Channels part of the namespace, so it should've been:

    "use 'System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(IChannel chnl, bool ensureSecurity) instead"

    ok, that was the first part, now if this overload is obsolete, which one is the equivalent?

    RegisterChannel(chnl, true)

    or

    RegisterChannel(chnl, false)

    Reflector to the rescue, the equivalent is to use false as the second parameter, that's what the current function does right now when you call

    RegisterChannel(chnl);

    it calls:

    ChannelServices.RegisterChannelInternal(chnl, false);

    Monday, August 14, 2006

    First bug in live write

    This happens when you add multiple blogs accounts, on the last dialog if you uncheck the "switch to this blog now" (or something like that) the new blog won't appear in your list of blogs, so you are not able to switch to that

    restarting the app refreshes the list

    Hello world from live writer

    This thing is pretty cool, it allows me to write to my multiple blogs just fine, check out their blog too

    cool use of the coallesce ?? operator in C#

    We just coded something like (please disregard the variable names, I'm just illustrating the point)

    return myCollections.Services ?? (myCollections.Services = dbLayer.GetServices());

    one-liner to do a bunch of stuff, and it's still clear what you are trying to do, if you know the ?? operator you can stop right here, if you don't let me explain a bit more

    the ?? operator returns the left-hand operator if it is NOT NULL, else it returns the right operand

    so this code is the equivalent of:

    if (myCollections.Services == null)

      myCollections.Services = dbLayer.GetServices();

    return myCollections.Services;

    Wednesday, August 09, 2006

    Notepad hidden features: How to use Notepad to create a (manual) log file

    In case you missed it, here's how "Bush hid the facts"
    To create a log file in Notepad:
    1. Click Start, point to Programs, point to Accessories, and then click Notepad.
    2. Type .LOG on the first line, and then press ENTER to move to the next line.
    3. On the File menu, click Save As, type a descriptive name for your file in the File name box, and then click OK.
    When you next open the file, note that the date and time have been appended to the end of the log, immediately preceding the place where new text can be added.
    You can use this functionality to automatically add the current date and time to each log entry.

    How to Use Notepad to Create a Log File

    Pretty cool, everytime you open the file after that (in Notepad), it adds a timestamp
     and you can enter some text

    get Delphi for free

    seems like things are starting to get shape for Borland's Developer Tools Group, they are coming up with these "express" (free) and cheaper versions of Delphi, C# and C++
    Turbo Delphi, Turbo Delphi for .NET, Turbo C++ and Turbo C# will be generally available in the third quarter of 2006. The Turbo Explorer editions of these products will be free. Pricing for the Turbo Professional editions will be under $500. Student academic pricing for the Turbo Professional editions will be under $100. For more information, visit www.turboexplorer.com.

    August 8, 2006 - Turbos Press Release

    We'll see what they can do against the Microsoft Express versions which have been out and free for a while, right now I don't see how they could compete but we'll see; if they run (and probably will) against the .NET Framework 1.1 that will discourage a lot of people

    Monday, August 07, 2006

    I'm natural hacker material J

    Points For Style
    Again, to be a hacker, you have to enter the hacker mindset. There are some things you can do when you're not at a computer that seem to help. They're not substitutes for hacking (nothing is) but many hackers do them, and feel that they connect in some basic way with the essence of hacking.
    * Learn to write your native language well. Though it's a common stereotype that programmers can't write, a surprising number of hackers (including all the most accomplished ones I know of) are very able writers.
    * Read science fiction. Go to science fiction conventions (a good way to meet hackers and proto-hackers).
    * Train in a martial-arts form. The kind of mental discipline required for martial arts seems to be similar in important ways to what hackers do. The most popular forms among hackers are definitely Asian empty-hand arts such as Tae Kwon Do, various forms of Karate, Kung Fu, Aikido, or Ju Jitsu. Western fencing and Asian sword arts also have visible followings. In places where it's legal, pistol shooting has been rising in popularity since the late 1990s. The most hackerly martial arts are those which emphasize mental discipline, relaxed awareness, and control, rather than raw strength, athleticism, or physical toughness.
    * Study an actual meditation discipline. The perennial favorite among hackers is Zen (importantly, it is possible to benefit from Zen without acquiring a religion or discarding one you already have). Other styles may work as well, but be careful to choose one that doesn't require you to believe crazy things.
    * Develop an analytical ear for music. Learn to appreciate peculiar kinds of music. Learn to play some musical instrument well, or how to sing.
    * Develop your appreciation of puns and wordplay.

    How To Become A Hacker

    Saturday, August 05, 2006

    The problem of naming your blog after a technology

    Specially at Microsoft, technology names change and some times they change often, I've seen quite a few blogs named after MS technologies that later change the name, some recent examples include Windows Vista and PowerShell

    You can't know it all, so what to do?

    You can't know it all. No matter how smart you are, no matter how comprehensive your education, no matter how wide ranging your experience, there is simply no way to acquire all the wisdom you need to make your business thrive.Donald Trump - Learning - Business - Knowledge

    Learning Quotes


    In the programming world we hear this more and more often, frameworks have thousands of classes, functions and features, even the people behind those frameworks don't know other parts of the framework, what makes you think you can know it all

    It's key to be comfortable with your own ignorance. Understand that you can't know it all and stop trying to or pretending that you do. Understand that other people are ignorant too, and help educate them when you can rather than resenting their shortfall. On the same track, don't resent someone who's trying to teach you something either, swallow your pride and better yourself for it.

    The Critical Path / eMail Newsletter / Issue 6.1



    My approach to this issue is to learn the language features as good as I can, then on the features of the frameworks I make a distinction on technologies that I'm interested in learning right now and learn them, and as many others that might be useful at some point, but the point is to be aware that such features exist and what they do; that way when you actually need them you can find them a lot faster because you know there is something to do just that and you avoid reinventing the wheel in many cases

    services like del.icio.us can help you with this problem, if you see something cool that you might be interested in the future you can save a link and tag it with something like "future" and you can build a list of things to learn or that you can posibly use some time later

    You can't put everything in your brain, so use the existing tools to do some of that work for you

    Is just like in soccer, is always good to win, but if you can't win is good to tie, if you can't tie is good to lose for as little difference as possible

    Improve your tabbed browser experience

    These extensions greatly improve the tabs behavior in Firefox/Flock

    Ctrl Tab Preview
    This is an extension that replaces the behavior of Ctrl+Tab. Instead of directly changing tab it works some thing like Alt+Tab on windows. It views preview of the tab and you can change directly to the tab you want to or just go through all tabs to see what you got in them. A pictures tells more then thousands words so look at the pictures or try it.


    SessionSaver
    SessionSaver restores your browser -exactly- as you left it, every startup, every time. Not even a crash will phase it. Windows, tabs, even things you were typing -- they're all saved. Use the menu to add + remove sessions; right, shift, or middle-clicking will delete. "Simple mode" for peace of mind, or "Expert mode" for advanced flexibility. Just Click. Install. Rad.

    Perma Tabs
    Adds the ability to turn tabs of your choice into permanent tabs ("permaTabs") that can't be closed, and stick around between sessions.

    Multiple home pages in your browser

    One of those things that not many people know, most modern browsers these days allow multiple home pages.

    Firefox/Flock



    Internet Explorer



    Opera also allows you to do it, quite a bit more complicated, but can be done

    Multiple home pages in Opera

    In Firefox/Flock there is also an extension that allows you to cycle your home pages:

    Home Page Cycler
    Load a different home page each time Firefox starts.

    Tuesday, August 01, 2006

    Don't click it, really

    quite a different user interface, what do you think?

    Don't click it

    Sunday, July 30, 2006

    using the right tool for each job, which web browser do you use?

    I use 5 different browsers approximately as:

    70% - Flock - This is like a Firefox on steroids (actually based on the Firefox engine), allows me to blog from it, integrates with flickr, etc, Any firefox extension that I use, I load on this browser

    10% - Firefox - I use this browser pretty much clean of all extensions, when I want to load a site and leave it running on the background I use this browser.

    10% - Internet Explorer 7 - Beta 3 at this point, so far I like it a lot, but there are a bunch of sites that just refuse to work with it, once it becomes a release version I'm sure I'll use it more

    5% - Internet Explorer 6 - On the other hand, there are some sites that only look good or only allow Internet Explorer 6, I use this browser for IE specific sites and/or sites that I trust (e.g. intranet)

    5% - Opera - Since out of my list of browsers, this is the least used, this kinda gives me more "protection" when I'm visiting sites that I don't trust that much (e.g. sites about hacking)

    Friday, July 28, 2006

    new class for creating SQL connection strings in .NET 2.0

    I just found about this little gem, I've seen all kinds of wicked code to create a sql connection string, anything from storing the whole connection string, to concatenating the string, to using a StringBuilder, etc. This class allows you to do all of the above but easier
    SqlConnectionStringBuilder Class Note: This class is new in the .NET Framework version 2.0.Provides a simple way to create and manage the contents of connection strings used by the SqlConnection class

    SqlConnectionStringBuilder Class (System.Data.SqlClient)

    once you create an instance of that class, you can read/write to the individual items of the connection through properties or through the indexer as:

    //you could pass the connection string in the constructor too

    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

    //using the indexer

    builder["DataSource"] = "someDataSource";

    //or using the property

    builder.DataSource = "someDataSource";

    this would be useful in a number of cases, for example if you had two connection strings that were different only by the server name

    technorati tags:, ,

    Thursday, July 27, 2006

    Google help

    With so many google products, it was about time to have a central place to look, first for all the available products, second, for help on how to use them
    Those of us in user support had a pet peeve: there was no single place that held all of Google's help information at your fingertips. So we decided to build one -- and now you can visit Google Help to find tips, tricks, and troubleshooting solutions for just about every Google product and service. We don't want you to have to work hard to find anything, so we also added an A-Z guide in case you do know exactly what you're looking for.

    Official Google Blog: A roadmap for Google help

    technorati tags:

    How to capture a PowerShell terminal session

    Just found about this cmd-let that captures all the input/output in Powershell

    to start it simply type:

    Start-Transcript

    it will tell you where the transcript is being stored, by default it creates a text file on your "c:\documents and settings\user\..." folder, but you can specify where you want the transcript to be stored just passing a file name after the cmd-let, you can also pass -append so that if the file exists, it keeps adding to it

    To stop it:

    Stop-Transcript

    This is kinda the equivalent to the unix script command

    technorati tags:

    Free MSDN library from now on

    For the first time, we're making the MSDN Library freely available for download from Microsoft Downloads. Previously, the Library was only available for download to MSDN subscribers. The current download is the May 2006 Edition and future editions will also be available when we release them.

    Rob Caron : Free Download: MSDN Library May 2006 Edition



    now this is great news!

    Tuesday, July 25, 2006

    Crazy windows bug

    Captured in video for all you windows-haters viewing pleasure, it has sound
    CRAZY COMPUTER BUG

    YouTube - CRAZY COMPUTER BUG

    Ruby for Visual Studio 2005

    Found this today at TSS.net, Ruby in Visual Studio, for those of you interested in alternative languages
    Ruby in Steel for Visual Studio 2005Posted by: Regina Lynch on July 25, 2006SapphireSteel Software will be releasing Ruby in Steel, a Ruby add-in allowing developers to take advantage of the Visual Studio IDE. The product will include debugging, Intellisense, code completion, code snippets and support for Rails.With the 1.0 release, both a free personal version and a developer version will be available. The developer version will include more advanced functionality, such as a fast debugger. SapphireSteel is planning to release several beta versions prior to release in order to implement further VS features and fix reported bugs.Ruby in Steel version 0.7 is currently available for download. It includes a Rails New Project Wizard, import capabilities, integrated SQL Server development, automated database setup and syntax error checking.

    Ruby in Steel for Visual Studio 2005

    check it out

    Ruby In Steel

    Saturday, July 22, 2006

    10 years ago, today

    It was July 22, 1996, back in my hometown in Mexico when I joined the company that I work for today, for most people to hear that someone has been working this long for the same company is quite shocking, for a few others it would be normal; for me it has been a great experience, I've grown a lot, I've had opportunity to meet a lot of people in many different cities.
    10 years... that's a long time, it's the difference between being 19 or 29 years, I hope I have been able to help some people through my work.

    Fortunately I won't have to bring a pound of chocolate per every year at the company or anything like that

    Thursday, July 20, 2006

    Windows Shortcut keys

    I found this short useful well formatted list of Windows shortcut keys, so you can impress your friends "how did you do that?"

    These shortcut keys work fine in Remote Desktop

    Windows Shortcut Keys

    Wednesday, July 19, 2006

    PowerShell:Get a list of paths from the environment variable PATH

    First of all, to get access to a variable from the environment you run:

    $env:[variableName]

    so, to get the PATH you do:

    $env:path

    on my machine, I get something like this:

    PS C:\> $env:path
    C:\oracle\product\10.1.0\Db_1\bin;C:\oracle\product\10.1.0\Db_1\jre\1.4.2\bin\c
    lient;C:\oracle\product\10.1.0\Db_1\jre\1.4.2\bin;C:\Oracle\product\10.1.0\Clie
    nt_1\bin;C:\Oracle\product\10.1.0\Client_1\jre\1.4.2\bin\client;C:\Oracle\produ
    ct\10.1.0\Client_1\jre\1.4.2\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\Syst
    em32\Wbem;C:\Program Files\Microsoft SQL Server\80\Tools\BINN;c:\Program Files\
    Microsoft SQL Server\90\Tools\binn\;C:\Program Files\QuickTime\QTSystem\;C:\Pro
    gram Files\Support Tools\;C:\Program Files\Windows PowerShell\v1.0\
    PS C:\>

    that's kinda hard to read, so you can use this method instead:

    $env:path.Split(';')

    PS C:\> $env:path.Split(';')
    C:\oracle\product\10.1.0\Db_1\bin
    C:\oracle\product\10.1.0\Db_1\jre\1.4.2\bin\client
    C:\oracle\product\10.1.0\Db_1\jre\1.4.2\bin
    C:\Oracle\product\10.1.0\Client_1\bin
    C:\Oracle\product\10.1.0\Client_1\jre\1.4.2\bin\client
    C:\Oracle\product\10.1.0\Client_1\jre\1.4.2\bin
    C:\WINDOWS\system32
    C:\WINDOWS
    C:\WINDOWS\System32\Wbem
    C:\Program Files\Microsoft SQL Server\80\Tools\BINN
    c:\Program Files\Microsoft SQL Server\90\Tools\binn\
    C:\Program Files\QuickTime\QTSystem\
    C:\Program Files\Support Tools\
    C:\Program Files\Windows PowerShell\v1.0\
    PS C:\>

    ah... much better

    what? you need the list on a file?

    $env:path.Split(';') > list.txt

    technorati tags:,

    Technical terms in your language

    I found this document: Microsoft Terminology Translations, via Edgar

    the document contains almos 15,000 terms in 47 different languages, so if you speak another language, chances are you'll find it there

    Tuesday, July 18, 2006

    quickly find out which version of the .NET framework is installed on a system

    This is something I have answered several times to many people, anything from production personnel to network administrators

    is quite easy (the yucky using the mouse way)

    You go to the control panel, Add or Remove Programs, wait forever for that to populate the list, then go find "Microsoft .NET Framework X.X"

    if you want to do it quicker than that, you can use this method instead:

    open a folder to:

    c:\WINDOWS\Microsoft.NET\Framework\

    or whatever the equivalent on your machine is, like

    c:\WINNT\Microsoft.NET\Framework\

    first of all, if the folder c:\windows\Microsoft.NET doesn't exist, then you don't have any .NET framework version installed

    Then, if you do get to that folder, you should see some folders like

    v1.0.3705

    v1.1.4322

    v2.0.50727

    That's the version of the .NET framework installed (the first two digits matter the most)

    It's also important to note that just because the folders exist there it doesn't mean that version is installed, to make sure you would actually have to go inside the folder and see that it has a ton of files (100+) and about 6-10 folders

    for ~95%+ of the cases though, I just type c:\WINDOWS\Microsoft.NET\Framework\v at the "run" window and see what shows up and that works just fine

    technorati tags:,

    Microsoft acquires sysinternals

    yup, the company that created filemon, regmon, tcpview, autoruns and so many other really cool tools is now part of Microsoft
    I’m very pleased to announce that Microsoft has acquired Winternals Software and Sysinternals. Bryce Cogswell and I founded both Winternals and Sysinternals (originally NTInternals) back in 1996 with the goal of developing advanced technologies for Windows. We’ve had an incredible amount of fun over the last ten years working on a wide range of diverse products such as Winternals Administrator’s Pak, Protection Manager, Defrag Manager, and Recovery Manager, and the dozens of Sysinternals tools, including Filemon, Regmon and Process Explorer, that millions of people use every day for systems troubleshooting and management. There’s nothing more satisfying for me than to see our ideas and their implementation have a positive impact.

    Mark's Sysinternals Blog: On My Way to Microsoft!

    technorati tags:

    Blogged with Flock

    Monday, July 17, 2006

    PowerShell support for old command line behavior

    While playing with PowerShell I noticed that it has pretty good support for the behavior found in "old" CMD and/or "DOS", all the function keys work just as expected

    Now, in case you don't know how to use the function keys in "DOS" here are some pointers:

    F1 - will repeat the last command one character at a time, so if your last command was "dir", you will get "d", "i", "r" as you press F1 multiple times

    F2 - "Copy up to char" function (of the last entered command): Not used much, it allows you to copy up to the character you enter after pressing F2, e.g.

    If you previously entered: dir "program files"

    on the next line you could enter: dir [F2]m

    and it would complete it as: dir "progra

    F3 - repeats the last command

    F4 - "delete up to", I can't really remember how to use this one, but is rarely used I guess

    F5 - iterate backwards through the list of previously entered commands (same as using the up arrow key)

    F6 - ^Z or text file terminator: I can't see how to use this in PS, but if you were entering a text using "copy con [filename]" you can get out of it and save the file by pressing F6, which by the way, PS doesn't have support for "copy con" but supposedly this guy wrote something equivalent to it:

    http://tfl09.blogspot.com/2005/10/monad-and-command-console.html

    F7 - Provides a list of the previously entered commands and you can select one using the arrow keys

    F8 - Iterates in a loop backwards (when it gets to the first one it goes the last one) through the previously entered commands

    F9 - "Enter command number": allows you to enter the command number you want to execute, to find out the command numbers you would have to use F7 first

    technorati tags:, , ,

    Blogged with Flock

    Sunday, July 16, 2006

    (PS) how to get back "home"

    I have a story of being a keyboard guy and a "command line guy", recently I have been interested in PowerShell; thanks to the secret geek I was encouraged to download it and try a few things, so far I'm loving it!, it's awesome... of course this is definitely not for everyone, specially not for programmers =o(, at least the great mayority of the ones I know don't really like command line stuff, anyway (is not like you are required to be an expert on it, PowerShell is oriented at System Administrators, I just happen to prefer command line when working at a computer, is just so much faster to accomplish things).

    I was reading on the secret geek blog about one of the cmd-lets:"Get-PSDrive":

    Once Upon A PowerShell i went looking for a cmdLet to display a list of all the current drives.I found one, 'Get-PSDrive' which does exactly that... but i was gobsmacked at what else it revealed!'Power shell drives' are not just your boring old 'C:' etc -- they can be all sorts of hierarchical structures, such a registry keys, environment variables, functions(!) and more.

    Babysteps in PowerShell part deux: Variables! Real Proper Variables!

    on mi machine it displays something like:

    PS C:\> get-psdrive

    Name       Provider      Root
    ----       --------      ----
    A          FileSystem    A:\
    Alias      Alias
    C          FileSystem    C:\
    cert       Certificate   \
    D          FileSystem    D:\
    E          FileSystem    E:\
    Env        Environment
    F          FileSystem    F:\
    Function   Function
    HKCU       Registry      HKEY_CURRENT_USER
    HKLM       Registry      HKEY_LOCAL_MACHINE
    Variable   Variable


    PS C:\>

    notice those Function, HKCU, HKLM and Variable at the end...

    you can do a "cd Variable:" then do a "ls" or "dir" and it will list the variables declared, you can do "cd Alias:", then "dir" will list the aliases in the system (alias for the different cmd-lets")


    anyway, I was playing with those and for a few seconds I was stuck when I did "cd Alias:", after finding out what was there, I wanted to go back, so I immediatly did "cd ..", didn't work, "cd \", nop... "cd /" nothing... panic!

    quite simple actually, we just need "c:" or "cd c:"

    (uff, that was close)... and now I have a new category to blog about

    technorati tags:,

    Thursday, July 13, 2006

    Time to update .NET 2.0

    This Information Disclosure vulnerability could allow an attacker to bypass ASP.Net security and gain unauthorized access to objects in the Application folders explicitly by name. Note that this vulnerability would not allow an attacker to execute code or to elevate their user rights directly, but it could be used to produce useful information that could be used to try to further compromise the affected system.

    Microsoft Security Bulletin MS06-033: Vulnerability in ASP.NET Could Allow Information Disclosure (917283)

    technorati tags:,

    Wednesday, July 12, 2006

    Tuesday, July 11, 2006

    Singleton Pattern the way you should NOT do it

    found this code today at c-sharp corner
    public static SingleTon GetObject(){
    if(instance == null)
    instance = new SingleTon();
    ++m_nNofReference;
    return instance;
    }

    Singleton Pattern

    don't use it, it is not thread safe, you can read this instead if you want to learn about the singleton pattern

    technorati tags:, ,

    "googling" officially a verb now

    "This week googling officially became a verb. The 11th edition of the Merriam-Webster Collegiate Dictionary now includes “googling” (lower case g). Actually the Oxford English Dictionary (OED) beat them to the punch a month ago by listing Google (upper case g) in their authoritative lexicon of the English language. It’s about time. People have been using Google as a verb for years, despite protestations by the company (many of which I authored myself) about the genericization of the trademarked name."

    check it out

    technorati tags:

    Thursday, July 06, 2006

    Bush hid the facts?

    1.) Open an empty notepad file.
    2.) Type "Bush hid the facts" (without the quotes).
    3.) Save it as whatever you want.
    4.) Close it, and re-open it.

    ...

    now for the spoiler, try the same thing with

    "this app may break"

    or

    "aaaa aaa aaa aaaaa"

    technorati tags:,

    Monday, July 03, 2006

    .NET Framework 3.0 structure

    in case this is still clear as mud, this picture should help

    technorati tags:,

    Tuesday, June 27, 2006

    what should I hide?

    I'm going through Code Complete 2 and got to this key point on chapter 5 about hiding information

    "Get into the habit of asking "What should I hide?" You'll be surprised at how many difficult design issues dissolve before your eyes."

    I think it should be quite the opposite, you should be in the habit of hiding everything and asking your self "what should I show?"; in C# if you omit the access modifier it defaults to private, and that's there for a good reason

    You have to think in terms of what would someone else do, if they were trying to mess up with your code or get that precious information that your project is accessing

    Of course not all projects are that critical that you should worry about securing every single aspect of the application, but you should get into the habit of hiding as much as possible and only making visible what you actually need, that way you'll be programming in a more secure way by default without even thinking about it

    Monday, June 26, 2006

    share keyboard and mouse accross computers (software driven)

    This little tool allows you to share your keyboard and mouse accross multiple computers, even with different Operating Systems loaded, that's pretty dang cool

    the only thing is that the configuration part of it is really buggy and makes the program die after it gives you the error message, basically you have to use the default options or it will crash

    but after you get it working it does just what is supposed to without getting in the way, you don't have to switch from your laptop to your regular pc keyboard and back...

    basically what you have to do is
    - install the server in the machine where the keyboard and mouse is hooked phisically and
    - install the client on the machines where you want to use the same keyboard
    - then you start the app on the server,
    - chose the "share this computer's keyboard and mouse",
    - click the configure button,
    - add the "screens" (machines), in that screen you can specify if there are some corners where you don't want the mouse to go over to the other machine, just make sure you specify a size greater than zero, or it won't work
    -once you add your screens (normally 2), you go to the links

    where you specify something like:
    0 to 100% of the "right" of "main pc" goes to 0 to 100% of "secondary"

    basically saying the right part of the monitor on "main pc" goes to the other pc; you have to specify the other way too

    0 to 100% of the "left" of "secondary" goes to 0 to 100% of "main pc"

    click start (in both computers) and you're good to go, if you need to change the config, close the program (in both sides) open it again, and go in the configuration button (in the server only)

    I'm loving it =oP

    Tuesday, June 20, 2006

    .9 = 1

    this post has generated so many comments and is so interesting (if you're not that good at math) you have to check it out

    the point is simple:

    .9 (repeating) = 1

    not just close to 1... it is 1, if you don't believe it go check it out

    technorati tags:,

    Saturday, June 17, 2006

    VS2005 Set Multiple Startup projects

    To set multiple startup projects
    1. In Solution Explorer, select the solution.
    2. On the Project menu, click Properties. The Solution Property Pages Dialog Box opens.
    3. Expand the Common Properties node, and click Startup Project.
    4. Click Multiple Startup Projects and set the project actions.

    How to: Set Multiple Startup Projects

    This is more of a note for my self, but I'm sure a lot of people doesn't know about this feature, supposedly even the debugger attaches to the multiple projects, that's really useful when developing multi layered projects

    technorati tags:, ,

    Visual Studio Environment Animation Speed

    this is a little trick I hadn't heard of, some items in the Visual Studio IDE have animation, e.g. when you open/close the properties, solution explorer, etc windows, there is some animation to make the windows appear/dissapear, sure is visually nice, but if you're like me, you don't want little whistles taking up your computer resources, I've seen those animation get quite slow specially when I have my machine loaded with a bunch of other stuff

    there is a way to speed up those animations or even disable them completly

    in the menu Tools, Options, Environment, General

    bump "animation speed" all the way up, or uncheck the "animate environment tools" checkbox to disable this feature

    this applies to both VS2003 and VS2005

    Wednesday, June 14, 2006

    blogging from flock

    this is just a test from the flock browser, it has built in blogging capabilities and some other goodies, is based on Firefox, so check it out

    Friday, June 09, 2006

    World Cup live scores and schedules from google

    Yesterday Edgar posted about a little program written by Microsoft to keep track of scores and stuff on the World Cup, and I just noticed that google has created something similar, but right into their web page

    nice!

    MSDN VS2005 & 2.0 framework Wiki

    this is nice, Visual Studio 2005 and the .NET framework 2.0 documentation now on a wiki where everyone can collaborate

    good job MS

    Thursday, June 08, 2006

    browser sync for Firefox

    "Google Browser Sync for Firefox is an extension that continuously synchronizes your browser settings – including bookmarks, history, persistent cookies, and saved passwords – across your computers. It also allows you to restore open tabs and windows across different machines and browser sessions."

    I don't know that I could use this, but probably some people would find it useful, I prefer to use delicious for that kind of thing, but anyway...

    notice how it is only for Firefox... evil google!