CopySourceAsHtml is a great Visual Studio plugin that i use to post my source code on this blog. The author has recently released a version that fully supports Visual Studio 2008. You could already use the old version with VS2008, but you had to do some things manually to get it working... this new version comes with an installer and some nice new features too. If you need to display source code from Visual Studio in HTML form, this plugin is exactly what you need ![]()
Archive for October, 2008
New Version Of CopySourceAsHtml Available
Career Advice For Young Developers
Over the past few years, i've seen a few young developers make some not-so-smart decisions about their careers and futures. I've always found situations like that frustrating because i hate seeing good developers make bad choices. So i decided to write down a bit of career advice for young developers:
Make sure you like doing your job
To me, one of the most important parts of a job is the fact that you should enjoy doing it. If you do the math, you'll quickly realize that you'll spend somewhere around half of your active adult life at your job, so you might as well try to make the most of it. If you're unhappy or frustrated at your job, you're essentially wasting a large part of your life so you're better off trying to find something that you actually enjoy doing.
Make sure you get satisfaction out of your job
A lot of people want different things out of their job, so it's hard to quantify those. For some people it's really important that their work is actually useful or helpful to others. Other people might get more satisfaction out of the fact that they are continuously increasing their skills. Other people want to make sure they work on very profitable stuff. Whatever it is that satisfies you in your job, make sure you get it. It keeps you motivated, it keeps you sharp and it helps in keeping you happy in general. Keep in mind though that there will always be days or short periods of time where you don't feel like you're getting that satisfaction out of your job. It's only natural that this happens once in a while, but if you feel like that on a regular basis, you're probably better off looking elsewhere for something that suits you more.
Choose between actual jobs, not companies
If you have to choose between jobs, go for the job that seems the most interesting and fulfilling. Do not base your decision on the actual companies offering the jobs. Always keep in mind that there are plenty of developer jobs out there (especially if you're good) so you don't really need to focus on stuff like job security. This can be different if you already have a family to feed, but then again, this advice is targeted to young developers. Go for the job that interests you the most, it will usually enable you to grow as a developer and increase your skill level substantially (which in the long run is the only true way to achieving job security anyway... more on that later).
If you like developing software, then keep working as a developer!
Developers that start working for larger companies often feel the need to climb up the corporate ladder to achieve some sort of management job. Because managers are important right? If you want to make it into management, you better be very sure that it's really something you want to do. Be prepared to be stuck in meeting rooms with people who often don't really know what they're talking about and are often only interested in advancing their careers, even if that means if it has to be at the cost of others. If you're a good developer and you like developing, there's absolutely nothing wrong with staying a developer. There are far too few good senior developers, and those people are always in heavy demand.
Don't put up with being a Code Monkey
Some developers are often considered as Code Monkeys, and they don't really get a lot of respect. Those developers can be just as valuable as any other developer, so if you ever feel like people look at you as just a Code Monkey, there's no reason to put up with that. You'd be better off finding a job where the developers are treated and appreciated as the valuable resources that they are.
Learn from your co-workers
Make sure you can learn from the people you're working with. If you're stuck in a place where you feel that you aren't learning anything new from your co-workers, you can quickly become demotivated, which is a terrible way to spending large parts of your days. A job where you frequently learn new things from your co-workers is really a blessing. Not only are you getting better at what you do, you're basically getting better for free, without having to invest your personal time into it.
Keep up with new technologies and ways of working
As i just mentioned, it's very important that you learn from your co-workers. But that doesn't mean you shouldn't spend a bit of your own time into improving your skills. You don't need to spend hours a day outside of work on getting better, but a couple of hours here or there could really make a big difference into increasing your skills. Not only do you get better from it, it also enables you to improve the skills of your co-workers, which in turn makes you a more valuable developer. Learning from people is important, but allowing people to learn from you is just as important.
Don't focus on job security
I used to work at a large company in the financial industry. I was there as a contractor, so i wasn't a 'real' employee of the company. I did meet some young developers there that only started working there because it was a large company where they had job security and a chance to build a career for themselves. The thing is though, those large companies usually aren't a very satisfying place to work. Things take a long time to get done, and the bureaucracy alone is enough to drain you mentally after a few years. If that happens, you've probably found other ways to get some satisfaction and happiness out of your life, usually outside of your work hours. Odds are that you haven't really invested much in your technical skills, and before you know it, your skills are pretty much outdated, and you become less attractive as a potential hire for other companies. At that point, you're pretty much stuck at a crappy job. The job security you wanted at first is there, but you've lost a lot of options for you personally and you're now stuck in a crappy job. If you want long-term job security, the best way to achieve that is to just make sure that you're very good at what you do, and that you love doing it. If you're a great developer, you will always find a great job somewhere. Yes, even when things in this business aren't going too great. Great developers will always be in demand.
Don't let money dominate your decisions
I've seen promising developers leaving their jobs just so they could make more money somewhere else. Now, if you're sure that you're going to like the new job more, then you've obviously made a good choice. But it's important to be careful. You can always make more money somewhere else, but you often don't know what kind of crap you'll have to put up with to get that extra money. If you let money be the deciding factor, you might end up in situations where the only benefit of the job is the paycheck. If making money is your only goal in life, then you probably don't mind too much. If you want to enjoy your career, you're probably better off choosing the interesting jobs over the higher paying ones.
Always make sure you can leave your job if you're not happy there
A lot of companies offer nice benefits to their employees. Some of those benefits could tie you into the company for the long term and you should be careful about those. No matter how much you like a job, one bad management decision could change everything. If something like that happens, and you suddenly aren't happy in your job anymore, it really would be a shame if you feel like you can't leave due to financial consequences of having to drop those benefits. Financial institutions are especially good at this... they typically offer employee benefits for their financial products, and if those products (like a loan for a house) tie you into the company for a long time (like, 20 years or so) it might become hard to leave that job due to the extra money it'll cost you. Make sure you don't get caught up in a situation like that, and make sure you become great at what you do. If you are great, you'll usually end up with more financial flexibility anyway ![]()
In conclusion
I'm not going to claim that the advice outlined above is a guaranteed way of having a successful career as a software developer. Most of it is entirely up to you and the amount of work you're willing to put into it. I do think that the advice above can definitely help you avoid some bad situations that could otherwise sneak up on you.
If you want to add some advice to the list, or think i'm wrong about something, be sure to tell us in the comments ![]()
What NHibernate Related Topics Would You Like To Read About?
I currently have the following NHibernate related topics on my list of posts to write:
1) Exploring NHibernate Statistics 2) Getting Up To Speed With The Second Level Cache 3) Using NHibernate's Stateless Sessions Instead Of Regular Sessions
I might also write something about NHibernate's Event Listeners...
So anyways, what would you like to learn more about? If you have some suggestions, be sure to leave a comment and i might write a post about it.
Obviously, i can't promise these posts in a certain time frame, but the interesting ones will be written sooner or later ![]()
Looking For More NHibernate Information?
For those of you who are using NHibernate (or are interested in using it, and you should be), you should check out NHibernate Forge. It's basically a community site with a blog, a wiki, and lots of other NHibernate related goodies. My NHibernate related posts are also posted there, as well as other people's NHibernate related posts.
So if you want to learn more about NHibernate, be sure to check that site out and keep an eye on it. Also, if you're already using NHibernate and want to share your experiences with the rest of us, i encourage you all to start writing posts about it. You can put your posts on your own blog as well as on NHibernate Forge. I even include a link to the original post on my blog whenever i put one of the posts on NHibernate Forge so you could do that as well.
Another good place to learn more about NHibernate is the NHUsers mailing list on Google Groups. It's a bit high-traffic, but a lot of interesting things are discussed there and it's a great place to ask for help.
How To Write Testable ASP.NET UserControls
Ever since i wrote my How To Write Testable ASP.NET WebForms post i've had people asking me how to make it work with UserControls. I pretty much avoided UserControls with this approach for as long as i could, but for our current project we really had a need for it. So i started implementing this together with a coworker, and this is the solution we came up with.
Note: if you haven't read that post on how to write testable ASP.NET WebForms, be sure to read it first because this approach is very similar and i won't repeat all of the general concepts of the approach here.
In the implementation for WebForms, we call the pages Views, and they all implement their own interface which inherits from our own IView interface. Now we wanted something that would work both with UserControls and Web Parts. So we figured we should call both of them ViewParts and we have the following base interface that each ViewPart should implement:
public interface IViewPart
{
bool IsPostBack { get; }
IDictionary State { get; }
}
If you need more operations that each ViewPart should be able to offer, you can obviously just add whatever you want to this interface.
We also want each ViewPart to have its own Controller, which we call PartControllers. Since we want to be able to test both the ViewParts and their containing Views in isolation, each View's Controller can never communicate directly with the specific PartController(s) of the ViewPart(s) that it contains. So we first need the following base interface for each PartController:
public interface IPartController
{
IDispatcher Dispatcher { get; set; }
void AddInitialRequests();
void GetInitialResponses();
}
In our case, each PartController will need an IDispatcher instance to be able to communicate with our Request/Response Service Layer. So the IDispatcher reference is only necessary if you're using that as well. The idea is that the containing View's Controller needs to provide its IDispatcher instance to each contained ViewPart's PartController so the initial requests of each ViewPart can be sent to the service layer together with whatever initial requests the containing View's Controller needs to send when the View is loaded. That's basically what the AddInitialRequests and GetInitialResponses methods are for. Again, this is very specific to the usage of the Request/Response Service Layer, so you might want to put some entirely different basic operations in your base IPartController interface.
We need to be able to ask each ViewPart for its typed PartController, so we also have this interface:
public interface IViewPart<TPartController> : IViewPart
where TPartController : IPartController
{
TPartController GetPartController(IDispatcher dispatcher);
}
We also need to be able to ask each PartController for a typed instance of its ViewPart, so we also have the following interface:
public interface IPartController<TViewPart> : IPartController
where TViewPart : IViewPart
{
TViewPart ViewPart { get; }
}
And then our PartController base class looks like this:
public abstract class PartController<TViewPart> : IPartController<TViewPart> where TViewPart : IViewPart
{
protected PartController(TViewPart viewPart)
{
ViewPart = viewPart;
}
public TViewPart ViewPart { get; private set; }
public IDispatcher Dispatcher { get; set; }
public virtual void AddInitialRequests() {}
public virtual void GetInitialResponses() {}
}
Now, when we want to write UserControls that can work with this approach, we need to inherit from the following UserControl base class:
public class UserControl<TPartController> : System.Web.UI.UserControl, IViewPart<TPartController>
where TPartController : IPartController
{
protected TPartController Controller { get; private set; }
protected UserControl()
{
Controller = IoC.Container.Resolve<TPartController>(new { ViewPart = this });
}
public TPartController GetPartController(IDispatcher dispatcher)
{
Controller.Dispatcher = dispatcher;
return Controller;
}
public IDictionary State
{
get { return ViewState; }
}
}
When the UserControl is constructed, we retrieve an instance of the specific PartController through the IOC container, and we pass the newly created instance of our UserControl as the ViewPart dependency of the PartController.
What you've seen so far is all very abstract, so let's go over a small example. Suppose we have a View (DummyPage) which contains a ViewPart (DummyPart). First, let's create the DummyPart:
public partial class DummyPart : UserControl<IDummyViewPartController>, IDummyViewPart
{
}
Our DummyPart (the ViewPart) inherits from our UserControl base class and passes the interface type of our PartController as the type parameter of the UserControl. It also implements the IDummyViewPart interface (which is empty in this simple example):
public interface IDummyViewPart : IViewPart<IDummyViewPartController>
{
}
The IDummyViewPartController interface looks like this:
public interface IDummyViewPartController : IPartController<IDummyViewPart>
{
void SomeSpecificOperationForTheDummyViewPart();
}
The implementation of the DummyPartController looks like this:
public class DummyViewPartController : PartController<IDummyViewPart>, IDummyViewPartController
{
public DummyViewPartController(IDummyViewPart viewPart) : base(viewPart) {}
public override void AddInitialRequests()
{
// add some initial requests to the IDispatcher
}
public override void GetInitialResponses()
{
// retrieve the responses for the initial requests from the IDispatcher
}
public void SomeSpecificOperationForTheDummyViewPart()
{
// do something specific to the IDummyViewPart
}
}
So what do we have now? A reusable UserControl which has its own controller where the actual logic of the UserControl will be implemented. We can write unit tests for all of the logic that the UserControl needs to have. We can also reuse this UserControl in a Page, and do so in a manner which enables us to fake the implementation of the UserControl for the tests we'll write for the logic in that Page.
Suppose we have a DummyPage which contains the DummyPart UserControl. Our DummyPage implements the following interface:
public interface IDummyView : IView
{
IDummyViewPart DummyPart { get; }
}
The code of our actual DummyPage looks like this:
public partial class DummyPage : Page<DummyController>, IDummyView
{
protected void Page_Load(object sender, EventArgs e)
{
Controller.Load();
}
public IDummyViewPart DummyPart
{
get { return dummyPart; }
}
}
And the code of the DummyController looks like this:
public class DummyController : Controller<IDummyView>
{
private IDummyViewPartController partController;
public DummyController(IDummyView view) : base(view)
{
}
public void Load()
{
partController = View.DummyPart.GetPartController(Dispatcher);
if (!View.IsPostBack)
{
partController.AddInitialRequests();
SendOurOwnRequestsAndGetTheResponses();
partController.GetInitialResponses();
}
}
private void SendOurOwnRequestsAndGetTheResponses()
{
// this method would send some requests through the IDispatcher and
// retrieve the responses
}
}
In the Load method of the DummyController, we retrieve the DummyPartController and we can communicate with it. And since we're talking to an interface type, we can easily provide a mocked IDummyPartController instance for our unit tests.
This approach makes it possible to create UserControls which you can easily write unit tests for, and you can reuse the UserControls in containing pages while remaining the flexibility to write unit tests for those containing pages without being dependent on the actual implementation of the UserControl.