Friday, December 18, 2009

Learning Fluent NHibernate

So, I’m still working on the wife’s website and I caught myself not learning something new on the CRUD operations. I had created a simple LINQ to SQL (L2S) implementation and then thought…wait a tick…I should use Fluent NHibernate! I’ve only heard good things and I had started learning it a while ago and never could get my configuration right. Well this time I did and I’m going to show it to you.

You might want to read this previous post before you continue because it gives the back story and setup of the form. I will be implementing the “//Add to mailing list logic” comment on the first code sample on the previous post. I guess I will start with what that looks like and it uses StructureMap. I will post my implementation of StructureMap in my next post.

[AcceptVerbs(HttpVerbs.Post), ValidateModel(typeof(JoinMailingListForm)), ValidateAntiForgeryToken]
public string JoinMailingList(JoinMailingListForm form)
{
if (!ModelState.IsValid)
return "Invalid Email Address. Please press back or enable JavaScript.";

var subscriber = DependencyRegistrar.Resolve<IMailingListSubscriber>();
subscriber.Subscribe(form.SubscriberEmailAddress);

return "Successfully subscribed.";
}

I basically stole the DependencyRegistrar from the sample code in the ASP.NET MVC in Action book. Great book for those of you that don’t already own it.


Okay, so my IMailingListSubscriber is VERY simple and it looks like this:


    public interface IMailingListSubscriber
{
void Subscribe(string emailAddress);
}

Now I did create two implementations of this interface one with L2S and one with Fluent NHibernate. I’m only going to show the NHibernate one, but if you’re interested in how I did the L2S one, you can check out this post. My L2S implementation was basically the same with the AutoMapper and everything.


Let’s get to the fluent greatness!


Here is the implementation with Fluent NHibernate:


    public class MailingListSubscriber : IMailingListSubscriber
{
public void Subscribe(string emailAddress)
{
if (SubscriberExists(emailAddress)) return;

using(var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Save(
new Subscriber(emailAddress));
tx.Commit();
}
}

private static bool SubscriberExists(string emailAddress)
{
using (var session = NHibernateHelper.OpenSession())
using(var tx = session.BeginTransaction())
{
var subscriber = session
.CreateCriteria(
typeof (Subscriber))
.Add(
Restrictions.Eq("EmailAddress", emailAddress))
.UniqueResult<
Subscriber>();

tx.Commit();
return subscriber != null;
}
}
}

So let’s break this down line by line starting with the Subscribe method.


First thing I do is check to see if the email address already exists in the database. If it does, I return and show the success message. If it doesn’t, I continue by opening a NHibernate Session with a NHibernateHelper that I will go into in a minute. I pretty much took it straight off the NHibernate wiki and added the fluent to it. I originally did not have the BeginTransaction call, but NHibernate Profiler suggested that I add it and explained why here. NHibernate Profiler is a TERRIFIC tool and I believe it’s required if you’re going to be using NHibernate.


After the transaction is created, I call the save and pass a new instance of my Subscriber class. Afterward, I commit the transaction.


In the SubscriberExists method, I open a session and begin a transaction.


The next part is NHibernate and not Fluent NHibernate. Basically I’m saying “SELECT * FROM Subscriber WHERE EmailAddress=emailAddress” and the UniqueResult returns the Subscriber object instead of a list. I’m pretty sure I got this syntax from one of the NHibernate videos on TekPub. The actual SQL called by NHibernate copied from NHibernate Profiler looks like this:



SELECT this_.Id               as Id0_0_,
       this_.Email               as Email0_0_,
       this_.DateSubscribed as DateSubs3_0_0_
FROM   connect.MailingList this_
WHERE  this_.Email = 'email@email.com' /* @p0 */


After the query, I commit the tran and return whether or not the email address exists. There is probably a better way to do this with NHibernate, but I have not learned it yet!  Let us continue…here’s what the Subscriber class looks like:

    public class Subscriber
{
public Subscriber()
{
DateSubscribed =
DateTime.Now;
}
public Subscriber(string emailAddress)
{
EmailAddress = emailAddress;
DateSubscribed =
DateTime.Now;
}

public virtual Guid Id { get; set; }
public virtual string EmailAddress { get; set; }
public virtual DateTime DateSubscribed { get; set; }

public virtual bool Equals(Subscriber other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.EmailAddress, EmailAddress);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (Subscriber)) return false;
return Equals((Subscriber) obj);
}

public override int GetHashCode()
{
return (EmailAddress != null ? EmailAddress.GetHashCode() : 0);
}
}

Notice there is an empty constructor, which is required by NHibernate. I go ahead and initialize some properties with default values in the constructors. One weird thing that happened when I started debugging is that when my initial test ran, NHibernate crashed in the configuration because I didn’t have an empty constructor. The message was clear when you read it, but at first I thought something was wrong with my configuration and not a class issue. The other thing that is a MUST with NHibernate is making your properties virtual. You will definitely get an error if you forget to add that little word.


So there you have the Subscriber class, now let me show you the SubscriberMap. This map is one of the things that makes Fluent NHibernate AWESOME! Especially if you’re not a fan of XML.

    public class SubscriberMap : ClassMap<Subscriber>
{
public SubscriberMap()
{
Table(
"connect.MailingList");
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.EmailAddress).Column(
"Email");
Map(x => x.DateSubscribed);
}
}

Basically, what this mapping file says is:



  • Use the connect.MailingList table

  • The Id is a generated Guid

  • The EmailAddress property is a column called Email

  • Then there is a property and column called DateSubscribed, which is why Column is not specified

That’s it! Now you’re mapped up from the Subscriber class to the DB table. You’ll notice it inherits from ClassMap<T>, which is in the FluentNHibernate.Mapping namespace. I guess I should mention in order to use Fluent NHibernate, just download it here.


One more thing you gotta do is configure NHibernate…FLUENTLY! So here is the NHibernateHelper that I mentioned earlier.

    public class NHibernateHelper
{
private static ISessionFactory _sessionFactory;

private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
_sessionFactory =
Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey(
"ConnectionString")))
.Mappings(m => m.FluentMappings.AddFromAssembly(
Assembly.GetExecutingAssembly()))
.BuildSessionFactory();
}

return _sessionFactory;
}
}

public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
All I’m doing is checking if the session factory exists if it doesn’t, configure and build it. You can read the tutorial that helped me with this setup here and you can watch TekPub’s video on the topic (TekPub Subscription Required) too. What it says is fluenty configure the database with MS SQL 2008 with this connection string from the connectionstring settings of the configuration file with the mapping files from the executing assembly and then build it. Pretty easy!

As always, please let me know if you see anything that I could improve or that I’m doing incorrectly. Thanks for reading!

kick it on DotNetKicks.com

Tuesday, December 15, 2009

Learning…A How to

I feel like I’ve been learning A LOT lately so I decided to write up a post on my learning process and some of the resources I’ve been using. So basically, I have to be in the mood to learn and sometimes…I realize I’m the fat kid running a 40 minute mile against my peers and their 5 minutes. Luckily it inspires me and kicks the competitive side of me into gear.

Typically, I won’t start using or learning something until I’ve read a TON of stuff about it. I think generally I want to make sure it’s worth learning and that it’s going to stick around for a while. I used to learn anything new that was out and immediately implement it and then I was burned a couple times…stupid datasets…ignorant young coder…poor first employer :)

So once I’ve read/listened/watched many blog posts, new books, videos, and podcasts, I start up a new project and give it a whirl. Now that I understand more of the smelly parts of my code, I know when I need to do more research…it’s like it doesn’t feel right and I can’t continue until I figure out the simplest way to do something. As some of you may or may not know, I work for a school district so simple is always better! I’m the app dev supervisor and we’re like a breeding ground for fresh developers right out of college that want experience…then they get it…then they leave us like a hot day in Texas…wait that can’t be right…how bout like a cow to greener pastures? I’ve never been good at similes…

On to the good stuff:

A Few of my Favorite Blogs to Read:

TIP: Setup Google Reader or some other blog reader…saves a TON of time!

Books I’ve read or are on my list…EVERY book on my to read list was recommended by someone

I also recently subscribed to Rob Conery’s TekPub for videos on various topics. So far, I’ve really enjoyed them. Rob makes me laugh and I’ve learned something new in every video I’ve watched.

Developers I follow & who generally respond to questions:

I think one of the best things about Twitter is that you have basically have a group of professionals there to ask a question or ask for a recommendation…it’s great!

Primary Web Resources:

As I think of more, I’ll certainly post and hopefully you’ll give me some good comments on what/who I’m missing. Have a good one and thanks for reading!

kick it on DotNetKicks.com

Sunday, December 13, 2009

Beauty of Interfaces

For those of you that don’t believe in interfaces and dependency injection, here’s one of the beautiful things about taking advantage of it.

If you haven’t read my last post, here’s a quick update of the project I’m working on. My wife has a photography business and she is wanting to update her site. Since I wanted to make it fun for me too, I decided to use all the best practices that I’ve learned thus far on an ASP.NET MVC project.

So basically, we started talking about using flickr to load her portfolio gallery and I had already coded it to load from the local machine. Since she wants to use the pics on her Facebook, her blog, and anywhere else that might be needed, we thought flickr was the way to go. Also, she really likes flickr’s upload and tagging system.

So since I was smart in the beginning thanks to all the different developers I follow, it was really simple to switch out all that code. The only thing I had to touch to switch out the entire photo repository was the structuremap code. Let’s get to the code:

Here is my IPhotoRepository interface, which is the only thing my UI knows about:

    public interface IPhotoRepository
{
IList<Photo> GetHomePhotos();
IList<Photo> GetPhotosBy(string portfolio);
}

GetHomePhotos is a method that returns the photos I loop through on the homepage with jQuery. The GetPhotosBy method is the meat of the project.


Here is my initial implementation of the IPhotoRepository, which loops through a particular directory.


public class PhotoRepository : IPhotoRepository
{
private readonly IDirectorySearcher _directorysearcher;
public PhotoRepository(IDirectorySearcher directorySearcher)
{
_directorysearcher = directorySearcher;
}

public IList<Photo> GetHomePhotos()
{
return GetPhotosBy("home");
}

public IList<Photo> GetPhotosBy(string portfolio)
{
portfolio = portfolio.Replace(
" ", "");
var photos = new List<Photo>();
foreach (var f in _directorysearcher.FindFilesStartingWith(portfolio))
if (!f.Name.Contains("_t"))
photos.Add(
new Photo() { Name = f.Name });

return photos;
}
}

Basically the way we planned on it working was through a naming convention and the wife would’ve had to create the thumbnails as well…now we just use flickr’s.


My new implementation takes advantage of flickr.net, so the calls to flickr’s APIs are really simplified. Here is the new implementation:


    public class FlickrPhotoRepository : IPhotoRepository
{
public IList<Core.Domain.Model.Photo> GetHomePhotos()
{
return GetPhotosBy("home");
}

public IList<Core.Domain.Model.Photo> GetPhotosBy(string portfolio)
{
var flickr = new Flickr("yourapikey");
var ps = flickr.PhotosSearch("yourflickruserid", portfolio, PhotoSearchExtras.OriginalFormat);
return Mapper.Map(ps.PhotoCollection, new List<Core.Domain.Model.Photo>());
}
}

There are a couple of things that are interesting about the above code. One is the PhotoSearchExtras.OriginalFormat, which returns a null for the original picture unless you upgrade to flickr pro. It took me about an hour to realize that that was the problem because it doesn’t really tell you to make sure you upgrade to pro in the error message. You just have to go read and research to figure it out.


The other interesting thing about the code above is the Mapper.Map, which is an automapper function. Here is my create map code, which resides in my automapper profile class. For more information about automapper, you can visit the automapper site or read my post on it.


            Mapper.CreateMap<FlickrNet.Photo, Photo>()
.ForMember(dest => dest.ImageUrl, opt => opt.MapFrom(src => src.OriginalUrl))
.ForMember(dest => dest.ThumbnailUrl, opt => opt.MapFrom(src => src.SquareThumbnailUrl))
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Title));

This is the beauty of interfaces because here is my PortfolioController:


    public class PortfolioController : SmartController
{
private readonly IPhotoRepository _photorepository;
public PortfolioController(IPhotoRepository photoRepository)
{
_photorepository = photoRepository;
}

public ActionResult Index(string name)
{
var pv = new PortfolioView {Name = name, Photos = _photorepository.GetPhotosBy(name)};
return View(pv);
}
}

See it has no idea that I completely changed the implementation of the photo repository. Another cool thing to mention I think is that the wife can add how many ever different portfolios that she wants. All she needs to do is create a tag and then go to /portfolio/newtagname and her site will load that particular photo list with that tag. So if you want to go to her weddings gallery, you’d go to /portfolio/weddings, if she had a preview for a client, she could do /portfolio/lastnameofclient and just not link that on her site. Anyhow, I thought it was cool. I don’t remember where I heard this, but some developer at some point told me it’s important to create hackable URLs so your end-users can guess at the URL.


So the only code I had to change to swap out the repository was this line:


            ForRequestedType<IPhotoRepository>().TheDefault.IsThis(new FlickrPhotoRepository());

That’s it! As always, please comment if you see anywhere that I could improve or you just have a comment. Thanks for reading!

kick it on DotNetKicks.com

Monday, December 07, 2009

jQuery AJAX with ASP.NET MVC

EDITED 12/8/2009 9:47PM

I’m in the process of re-building my wife’s photography website and she wanted to add a mailing list feature to the site. I didn’t want one of her users to have a page refresh on the page, so I wanted to make an AJAX call. So that’s the back story to why I started learning jQuery AJAX with ASP.NET MVC. I’m pretty new to MVC and the jQuery AJAX methods.

Here’s the setup:

On my ConnectController, I added a JoinMailingList action that looks like this:

 [AcceptVerbs(HttpVerbs.Post), ValidateModel(typeof(JoinMailingListForm)), ValidateAntiForgeryToken]
public string JoinMailingList(JoinMailingListForm form)
{
if (!ModelState.IsValid)
return "Invalid Email Address. Please press back or enable JavaScript.";

//Add to mailing list logic

return "Successfully subscribed.";
}


I will not get into the attributes other than to say the ValidateModel I got from the sample code for ASP.NET MVC in Action (GREAT BOOK) and the ValidateAntiForgeryToken I learned from a Phil Haack post.


My JoinMailingListForm looks like this:



using Castle.Components.Validator;

namespace UI.Models.Forms
{
public class JoinMailingListForm
{
[
ValidateNonEmpty(""), ValidateEmail("")]
public string EmailAddress { get; set; }
}
}

The validate attributes on the EmailAddress property are from the Castle.Components.Validator namespace.


My view control inherits from my BaseViewControl<T> class, which inherits from MvcContrib.FluentHtml.ModelViewUserControl<TModel> class. DO NOT forget to use this class if you want to take advantage of FluentHtml. I forgot this initially and it was really annoying.


Here is my ViewControl:


<%@ Control Language="C#" Inherits="UI.Helpers.ViewPage.BaseViewControl<JoinMailingListForm>" %>
<div id="joinmsg" style="display:none" class="validation-summary"></div>
<
form action="/Connect/JoinMailingList/" method="post" id="joinmailingform">
<
fieldset>
<
legend>Mailing List</legend>
<%=this.TextBox(f => f.EmailAddress)
.Label(
"Get discounts and more: ")
.Value(
"add email here")
.Attr(
"accesskey", "M")%>
<%
=Html.AntiForgeryToken() %>
<%
=Html.SubmitButton("join", "J") %>
</fieldset>
</
form>

As you can see, the control inherits from my BaseViewControl<TModel> and takes advantage of FluentHtml. I LOVE FluentHtml, I think it is very slick…I’ve grown to love all things fluent. The Html.SubmitButton is an extension method I added to the HtmlHelper.


Now for the jQuery AJAX call, which I decided to modify and take advantage of the jquery.form plugin from Mike Alsup:


<script language="javascript" type="text/javascript">
$(document).ready(
function() {
$('#joinmailingform').ajaxForm(function(data) {
if (data == 'Successfully subscribed.') {
$(
'input#EmailAddress').qtip({
content: 'Successfully subscribed.',
hide: { when:
'blur' },
show: { when:
false, ready: true, solo: true },
style: { name:
'blue', tip: true },
position: { corner: { target:
'topMiddle', tooltip: 'bottomMiddle'}}
});
} else {
$(
'input#EmailAddress').qtip({
content:
'Oops! Something went wrong.',
hide:
false,
show: { when:
false, ready: true, solo: true },
style: { name:
'red', tip: true },
position: { corner: { target:
'topMiddle', tooltip: 'bottomMiddle'}}
})
.addClass(
'input-validation-error');
}
});
});
</
script>

Basically, this is called as an action on my form and it calls the ConnectController and the JoinMailingList action. The .ajaxForm is part of the jquery.form plugin, which turns my form into an AJAX form. It handles the call for me and the real benefit to going this route is that even if JavaScript is disabled, my wife’s users can still subscribe to her mailing list. It’s not pretty without JavaScript, but it works. I’m now returning a string and displaying a message accordingly. I also went ahead and implemented qtip by Craig Thompson, which is all the .qtip({}) stuff. The qtip plugin is really sweet and has the look and feel that Amy wanted for her site.


That’s it! Pretty simple I thought and it was pretty fun to create. Please let me know if you see anything that I could improve or that I’m doing incorrectly. Thanks for reading!


Thank you Jon for the suggestion!

Shout it

kick it on DotNetKicks.com

Saturday, November 28, 2009

LINQ to SQL with AutoMapper

So remember my first post about LINQ to SQL? Well, I think I found a HUGE improvement over the mapping files thanks to Jimmy Bogard's AutoMapper. Take a look:

So I created a really simple domain model that looks like this:

After I created my domain model, I created a implementation project with a simple repository and a DBML file, which looks like this:




The repository code looks like this:

    public class PhotoRepository : IDisposable 
{
private readonly PhotosDataContext _dc;
public PhotoRepository()
{
Registry.
AutoMapperRegistry.Configure();
_dc =
new PhotosDataContext();
}

public List<Photo> GetAll()
{
return Mapper.Map<PhotoDataModel[], Photo[]>(_dc.PhotoDataModels.ToArray()).ToList();
}

public void Save(Photo photo)
{
Registry.
AutoMapperRegistry.Configure();
using (var dc = new PhotosDataContext())
{
dc.PhotoDataModels.InsertOnSubmit(
Mapper.Map<Photo, PhotoDataModel>(photo));
dc.SubmitChanges();
}
}

public void Dispose()
{
if (_dc != null)
_dc.Dispose();
}
}

So in the implementation project, I added my AutoMapper configuration. I setup two profiles one for the LINQtoSQL and then one to reverse it. Here's that code:

    public class AutoMapperRegistry
{
public static void Configure()
{
Mapper.Initialize(x =>
{
x.AddProfile<
LinqToSqlProfile>();
x.AddProfile<
LinqToSqlReverseProfile>();
});
}
}
    public class LinqToSqlProfile : Profile
{
protected override string ProfileName
{
get
{
return "LinqToSqlProfile";
}
}

protected override void Configure()
{
Mapper.CreateMap<PhotoDataModel, Photo>()
.ForMember(dest => dest.Photographer, opt => opt.MapFrom(src=>src.PhotographerDataModel));

Mapper.CreateMap<PhotographerDataModel, Photographer>();
}
}
    public class LinqToSqlReverseProfile:Profile
{
protected override string ProfileName
{
get
{
return "LinqToSqlReverseProfile";
}
}

protected override void Configure()
{
Mapper.CreateMap<Photo, PhotoDataModel>()
.ForMember(dest => dest.PhotographerDataModel, opt => opt.MapFrom(src => src.Photographer));

Mapper.CreateMap<Photographer, PhotographerDataModel>();
}
}

You'll notice in my repository I call the configure method twice once in the constructor and again on the save. I didn't have to do it in the save, but the way I did the console app, it was required. I could've called it before calling the save, but I wanted it all in one place to make it a little easier to read...I think it is anyhow.

So in order to flatten out my domain model like Headspring seems to practice and I try to mimic everything they do because lets face it, they're the best software company in the world. At least that's my opinion. So here is my view model:

    public class PhotoViewModel
{
public string Name { get; set; }
public string FileSize { get; set; }
public DateTime DateTaken { get; set; }
public string Description { get; set; }
public string PhotographerName { get; set; }
}

Here is my AutoMapper configuration for the UI project:

    public class ViewProfile:Profile
{
protected override string ProfileName
{
get{ return "ViewProfile"; }
}

protected override void Configure()
{
Mapper.CreateMap<Core.Photo, PhotoViewModel>()
.ForMember(dest => dest.PhotographerName, opt => opt.MapFrom(src => src.Photographer.Name));
}
}

Here's the initialization:

    public class AutoMapperRegistry
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<ViewProfile>());
}
}

Finally, here is my UI code that displays a list of the photographers and then saves a new one.

        static void Main(string[] args)
{
var pr = new PhotoRepository();
var photos = pr.GetAll();

AutoMapperRegistry.Configure();
foreach (var p in photos)
{
var photo = Mapper.Map<Photo, PhotoViewModel>(p);
Console.WriteLine("Photographer: " + photo.PhotographerName);
}
Console.Read();

var p1 = new Photo();
p1.Id =
Guid.NewGuid();
p1.Name =
"Test Photo";
p1.Photographer.Id =
Guid.NewGuid();
p1.Photographer.Name =
"John Smith";
p1.DateTaken =
DateTime.Now;
pr.Save(p1);
}


Download Source Here

Hopefully Jimmy reads this post and lets me know if there is anything messed up or anything that I'm not doing correctly with my mappings.

kick it on DotNetKicks.com

Related Posts Plugin for WordPress, Blogger...