Silverlight+WPF

Blog d'Alexandre Arnaudet et de ses collègues chez CLT-Services autour de WPF, de Silverlight et des RIA

Recent posts

Tags

Categories

Navigation

Pages

    Archive

    Blogroll

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    WPF / MEF – Exporter des données

    Qu’est ce que MEF ?

    MEF est un Framework permettant de développer des applications modulaires, composées de Parts. Vous trouverez d’un côté les Parts “Export” qui fournissent des services et de l’autre les Parts “Import” qui utilisent ces services. Dans l’utilisation de MEF que j’ai pu faire jusqu’à maintenant, j’ai tendance à dire qu’on a d’un côté l’application Core et de l’autre un ensemble de plugins respectant un contrat pour chaque service attendu.

    Dans ce billet, je vous propose de voir le développement de l’application core, et d’un plugin. Le second sera présent dans les sources disponibles à la fin du billet. Pour y parvenir considérons les points suivants:

    • Notre application est une application de type client lourd
    • Au niveau de l’UI nous affichons une liste d’objet Employee et proposons à l’utilisateur plusieurs possibilités pour exporter ses données
      • La première se fera via un fichier XML
      • La seconde quant à elle se fera vers un fichier Excel.
    • L’application utilise le pattern MVVM
    • Le model est constitué d’une seule entité nommée Employee.

    Le but de ce billet n’est pas de voir comment implémenter MVVM avec WPF, je considère que vous savez déjà le faire. A ce titre, nous allons partir d’un projet de base avec le ViewModel principal déjà créé. Pour cela, vous pouvez utiliser le Template de création de projet suivant.

    1- Création du model

    Comme dit plus haut, notre model va rester simple pour la démonstration. Il sera uniquement constitué d’une entité Employee ainsi que de quatre propriétés: LastName, FirstName, Age et Job. Vous remarquerez au passage que la classe hérite de NotifiableObjectBase qui donne la possibilité de notifier le changement d’une des propriétés. (Son code sera dans le zip à la fin du billet).

    Code classe Employee:

    public class Employee : NotifiableObjectBase
      {
          private string lastName;
          public string LastName
          {
              get { return lastName; }
              set
              {
                  if (value != lastName)
                  {
                      lastName = value;
                      base.RaisePropertyChanged<string>(() => LastName);
                  }
              }
          }
    
          private string firstname;
          public string FirstName
          {
              get { return firstname; }
              set
              {
                  if (value != firstname)
                  {
                      firstname = value;
                      base.RaisePropertyChanged<string>(() => FirstName);
                  }
              }
          }
    
          private int age;
          public int Age
          {
              get { return age; }
              set
              {
                  if (value != age)
                  {
                      age = value;
                      base.RaisePropertyChanged<int>(() => Age);
                  }
              }
          }
    
          private string job;
          public string Job
          {
              get { return job; }
              set
              {
                  if (value != job)
                  {
                      job = value;
                      base.RaisePropertyChanged<string>(() => Job);
                  }
              }
          }
    
      }

     

    2- MEF – Création du contrat pour les plugins.

    De manière à ce qu’un plugin soit accepté par l’application, il doit respecter un contrat. En code ce contrat est représenté par une interface, qui impose donc au plugin d’implémenter les méthodes et propriétés qui y sont spécifiées.

    Dans notre cas, comme nous voulons donner la possibilité à l’utilisateur d’exporter une liste de données vers un fichier Excel et XML, nous allons juste ajouter une méthode Save à notre interface.

    public interface ISave
    {
        void Save<T>(List<T> listToExport);
    }

    La méthode prend en paramètre une liste de données générique, ainsi nous pourrons par la suite, passer autre chose que des entités Employee si nécessaire.

    3 – Création d’un plugin

    Maintenant que le contrat est créé, nous pouvons passer à la réalisation du plugin. Dans un premier temps, nous allons créer un seul plugin correspondant à l’export vers un fichier XML.

    Pour la création du plugin, commencez par créer une nouvelle librairie. Cette librairie ne sera pas ajoutée en tant que référence dans un projet de la solution. Toutefois, nous allons spécifier une ligne de commande Post Build Event sur le projet pour que la dll finale soit copiée dans un répertoire spécifique aux plugins que nous allons nommer Extensions.

    Allez dans les propriétés du projet et après avoir sélectionné l’onglet “Build Events”, ajoutez la ligne suivante:

    copy "$(OurDir)"* "$(SolutionDir)MEFDemo\bin\$(ConfigurationName)\Extensions\"

    Une fois cette étape réalisée, ajoutons une classe que l’on appellera SaveToXml. Faites lui ensuite implémenter l’interface ISave. Dans la méthode générique Save nous allons utiliser une librairie que j’ai développé pour la sérialisation des données.

    public class SaveToXml : ISave
        {
            public void Save<T>(List<T> listToExport)
            {
                if (listToExport == null)
                    throw new ArgumentNullException("listToExport");
    
                string currentPath = Directory.GetCurrentDirectory();
                XmlHelper.SaveDataToXml<List<T>>(
                    Path.Combine(currentPath,"export.xml"),
                    listToExport, 
                    null);
            }
        }

    Encore une fois pour rester concentré sur le sujet, je ne montrerai pas ici le code de la librairie de sérialisation, mais sachez qu’il sera disponible à la fin du billet.

    En plus du fait que nous ayons besoin d’utiliser un contrat pour notre plugin, le Framework MEF a besoin qu’on ajoute un attribut ExportAttribute sur notre classe pour spécifier qu’il participe en tant qu’élément dans la composition de l’application dans le cadre du contrat ISave.

     [Export(typeof(ISave))]
     public class SaveToXml : ISave
    

    Enfin, nous allons ajouter une dernier attribut ExportMetadataAttribute qui comme son nom l’indique permet de définir des métadonnées sur notre classe. Ces métadonnées permettent d’ajouter des informations concernant le plugin également appelé Part dans le langage MEF. 

    Dans notre cas nous allons juste ajouter une méta pour donner un nom et identifier facilement le plugin auquel on à faire.

    [ExportMetadata("Name","xml")]
    [Export(typeof(ISave))]
    public class SaveToXml : ISave
    

    Nous pourrions nous arrêter là en ce qui concerne cette Part, mais nous allons développer notre propre attribut d’export pour les raisons suivantes.

    • Spécifier un seul attribut pour le contrat de l’export et les métadonnées.
    • Utiliser des métadonnées fortement typées.

    Pour cela notre attribut doit hériter de ExportAttribute se trouvant dans System.ComponentModel.Composition. Pour indiquer qu’il agit également comme un attribut de métadonnées, il nous faut ajouter sur notre attribut l’attribut MetadataAttribute. Enfin nous avons vu que la seule méta nécessaire ici est Name, nous allons donc ajouter une propriété Name de type string.

    [MetadataAttribute]
        [AttributeUsage(AttributeTargets.Class, 
            AllowMultiple = false,
            Inherited = false)]
        public sealed class SaveExportAttribute : ExportAttribute
        {
    
            public SaveExportAttribute()
                : base(typeof(ISave))
            {
            }
    
            public string Name { get; set; }
    
        }

    Maintenant que cela est fait, nous allons développer un service permettant d’accéder aux plugins ajoutés dans le répertoire Extensions et faire en sorte qu’il soit injecté via Unity dans le ViewModel nommé MainViewModel.

    Pour que ce service soit par la suite facilement mockable, nous allons passer par une interface.

    Ce que nous voulons avec ce service, c’est avoir:

    • une liste des plugins existant pour l’export.
    • une méthode d’export
    public interface ISaveService
       {
           IEnumerable<Lazy<ISave,ISaveMetadata>> AvailablePlugins { get; set; }
           void Save<T>(string pluginName, List<T> list);
       }

    Regardez la propriété AvailablePlugins.

    Vous remarquerez l’utilisation du type Lazy en tant qu’élément du IEnumerable<T>.  Ce type, nouveau dans le Framework 4, permet de différer la création d’un objet.

    En regardant d’un peu plus près la définition du type Lazy, on voit qu’on lui spécifie ici un deuxième type ISaveMetadata.

    Mef apporte une surcharge du type Lazy, avec lequel on peut également passer des métadonnées, et c’est là tout l’intérêt de la chose. Vous pouvez parcourir les métadonnées en quête d’informations avant même que l’objet soit instancié.

    Mais revenons au type ISaveMetadata. Dans notre exemple, il s’agit d’une interface dans laquelle on ajoute les données / métadonnées que l’on veut accessibles au client, ici le Name. En interne MEF, va se charger de créer un classe proxy implémentant cette interface et faire le mapping avec les métadonnées ajoutées avec ExportMetadata ou le custom attribute  SaveExportAttribute dans notre cas.

    public interface ISaveMetadata
    {
        string Name { get; }
    }

    A présent, après avoir vu la propriété AvailablePlugins, il nous reste la méthode Save à inspecter. Rien de bien compliqué en ce qui la concerne. On voit qu’il s’agit d’une méthode générique ce qui permet éventuellement de faire des exports basés sur un autre type que Employee, et qu’on lui passe en paramètre le nom du plugin qu’elle doit utiliser pour effectuer cet export.

    Du côté de l’implémentation réalisée dans ce projet, on retrouve ce que l’on vient d’expliquer.

    Notez quand même la présence de l’attribut ImportMany sur la propriété AvailablesPlugins pour indiquer à MEF qu’il doit découvrir toutes les Parts Export implémentant l’interface ISave

    Dans la méthode Save, nous récupérons simplement le bon plugin grâce à une petite requête linq. A cet instant précis, le plugin n’est pas encore instancié. Un peu plus loin l’instance de type ISave est enfin créée via l’appel à la propriété Value. Il ne reste plus qu’à appeler la méthode qui je le rappelle se trouve au  niveau de l’interface ISave.

    public class SaveService : ISaveService
       {
           [ImportMany(typeof(ISave))]
           public IEnumerable<Lazy<ISave,ISaveMetadata>> 
               AvailablePlugins { get; set; }
    
           public void Save<T>(string pluginName, List<T> list)
           {
               var lazyPlugin = AvailablePlugins
                   .FirstOrDefault(p => p.Metadata.Name == pluginName);
               if (lazyPlugin == null)
                   throw new Exception("Invalid plugin name");
    
               //plugin instanciation
               var plugin = lazyPlugin.Value;
               if (plugin == null)
                   throw new Exception("Plugin is not available");
    
               plugin.Save<T>(list);
           }
       }

     

    Au début de ce billet, j’avais précisé que la démo utilisait le pattern MVVM. Pour rendre ce service accessible au ViewModel, nous allons l’injecter via Unity dans son constructeur.

    public MainViewModel(IMainView mainView, ISaveService saveService)

    Dans notre ViewModel, nous allons ajouter une collection de type string qui va contenir les noms des plugins disponibles. Cette liste est construite à partir des informations que le service SaveService nous fait parvenir. La vue n’aura plus qu’à se binder pour afficher une liste de ces valeurs.

    foreach (var plugin in this.saveService.AvailablePlugins)
    {
        PluginsName.Add(plugin.Metadata.Name);
    }
    <ComboBox   ItemsSource="{Binding PluginsName}" />
    

    Enfin pour avoir quelques données à exporter, on créé également une ObservableCollection de type Employee, que la vue va afficher dans un DataGrid, et on lui ajoute des Employee, tous les même ici pour simplifier la démo.

    public ObservableCollection<Employee> Employees { get; set; }
    <DataGrid Grid.Row="1" ItemsSource="{Binding Employees}" />
    
    for (int i = 0; i < 20; i++)
                   Employees.Add(new Employee 
                   { 
                       Age = 25,
                       FirstName = "Alexandre",
                       LastName = "Arnaudet",
                       Job = "Ingénieur d'études" });

    Dernier  point à régler pour terminer l’UI et le ViewModel, déclencher l’appel à la méthode Save du service. Pour cela, ajoutons une ICommand dans le ViewModel que l’on va nommer SelectExportTypeCommand. Comme nous utilisons une ICommand de type RelayCommand, il nous faut également préciser le handler appelé lors de l’exécution de la commande, ainsi qu’une méthode indiquant si l’appel de la commande peut avoir lieu.

    public ICommand SelectExportTypeCommand
           {
               get
               {
                   if (selectExportTypeCommand == null)
                       selectExportTypeCommand =
                           new RelayCommand(
                               param => Export(param),
                               param => CanExport());
    
                   return selectExportTypeCommand;
               }
           }
    
           private void Export(object param)
           {
               
               this.saveService
                   .Save<Employee>(selectedExportPlugin,
                   new List<Employee>(Employees));
           }
    
           private bool CanExport()
           {
               return !string.IsNullOrEmpty(SelectedExportPlugin);
           }

    Au niveau de l’UI, un simple contrôle de type button utilisant sa propriété Command pour se binder sur la ICommand d’export. Voici un résumé du code XAML représentant l’UI.

    <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="*" />
                <RowDefinition Height="40" /> 
            </Grid.RowDefinitions>
            <TextBlock Text="Demo MEF" FontSize="24"  />
            <DataGrid Grid.Row="1" 
                      ItemsSource="{Binding Employees}" />
            <StackPanel Grid.Row="2"
                        Orientation="Horizontal">
                <TextBlock Text="Mode d'export:"
                           VerticalAlignment="Center" />
                <ComboBox   ItemsSource="{Binding PluginsName}"
                            Margin="5"  
                            SelectedItem="{Binding SelectedExportPlugin}"
                            Width="150"/>
                <Button Content="Exporter" Margin="5"
                        Command="{Binding SelectExportTypeCommand}"/>
                
            </StackPanel>
        </Grid>
    

     

    Avant de lancer l’application, nous allons jeter un coup d’œil à un dernier fichier nommé bootstrapper. Ce fichier est une simple classe appelée depuis App.xaml.cs au démarrage de l’application. On y configure le container unity dans le constructeur.

    public BootStrapper()
           {
               container = new UnityContainer();
               UnityConfigurationSection section =
                   (UnityConfigurationSection)ConfigurationManager
                   .GetSection(ConfigurationManager.AppSettings["UnitySection"]);
               section.Configure(container);
           }

    Dans un second temps, elle s’occupe également dans la méthode Load de faire la résolution du ViewModel principal et d’afficher la vue liée.

    L’utilisation de MEF implique la création d’un CompositionContainer, dans lequel on ajoute les Parts qui vont composer l’application. Ici on s’aperçoit que le CompositionContainer est construit à partir d’un catalogue de type DirectoryCatalog qui correspond au répertoire Extensions dans lequel se trouve les dlls avec les Export. Le service SaveService qui contient une propriété AvailablePlugins avec un Attribut Import est également une Part. On utilise donc la méthode ComposePart pour le signaler au container et lui dire de satisfaire les imports présents.

    internal void Load()
            {
                string directoryPath = Directory.GetCurrentDirectory();
                string fullPath = 
                    Path.Combine(directoryPath, 
                    ConfigurationManager.AppSettings["ExtensionsPath"]);
    
                var catalog = new AggregateCatalog();
                catalog.Catalogs
                    .Add(new DirectoryCatalog(fullPath));
    
                var mefContainer = new CompositionContainer(catalog);
                var service = container.Resolve<ISaveService>();
                mefContainer.ComposeParts(service);
    
                IMainViewModel mainViewModel = 
                    container.Resolve<IMainViewModel>();
                mainViewModel.View.ShowView();
            }
        }

    Le développement de l’application est terminé. Si vous la démarrez, vous devriez obtenir le résultat suivant avec juste un option pour l’export: xml. Vous pourrez trouver ce fichier xml dans le répertoire où l’application s’exécute.

    image

     

    Nous venons juste de voir que la résolution du ViewModel,  de la View et du Service était faite via Unity, mais après tout on peut très bien utiliser MEF pour réaliser cette opération.

    Pour cella il suffit comme on l’a fait avec l’export xml de placer les attributs Export et Import.

    • Placez l’attribut export sur le ViewModel:
    [Export(typeof(IMainViewModel))]
    • Placez l’attribut ImportingConstructor sur le constructor du ViewModel pour dire à MEF que ses paramètres deviennent des Import.
    [ImportingConstructor]
           public MainViewModel(IMainView mainView, 
               ISaveService saveService)

    • Placez l’attribut Export sur la View

     

    [Export(typeof(IMainView))]
    • Placez l’attribut Export sur le SaveService
    [Export(typeof(ISaveService))]

     

    • Modifiez le bootstrapper de manière à ajouter une propriété IMainViewModel avec un Import.
    [Import]
         public IMainViewModel MainViewModel { get; set; }
    • Faites un ComposePart du bootStrapper pour satisfaire l’import
    mefContainer.ComposeParts(this);
    • Affichez la vue
    if (MainViewModel != null)
                    MainViewModel.View.ShowView();

    Enfin avant de lancer l’application, supprimez les références vers MVVM.ViewModel, MVVM.View et MEFDemo.SaveService, et modifiez les post build event comme pour le plugin xml afin que les dlls soient déposées dans le répertoire Extensions.

    Vous pouvez télécharger l’ensemble des sources ci-dessous. Vous y trouverez notamment un deuxième plugin pour l’export de la même liste de données, mais cette fois ci vers excel.

    Sources et autres librairies: Télécharger.

    Posted: Aug 25 2010, 21:52 by Alexandre Arnaudet | Comments (138) RSS comment feed |
    • Currently 0/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5
    Filed under: MEF | WPF

    Comments

    topsy.com said:

    Pingback from topsy.com

    Twitter Trackbacks for
            
            WPF / MEF – Exporter des données
            [silverlightwpf.fr]
            on Topsy.com

    # August 29 2010, 00:56

    Bill Berg United States said:

    Cool site, I found your page looking for a hunting knife and knife making supplies.I ended up reading more than I expected and wanted to say thank you! If you ever think about learning how to make a knife you should check out www.knife-knife.com or www.knifecenter.us thanks!

    # November 21 2010, 23:35

    best annual travel insurance United States said:

    This text is really resourceful, I really stumbled upon this web site not knowing i would get this sort of rich content and knwoledge. I've also checked on different poss of yours they usually were fairly enlighten and educative. You actually did a pleasant job. Keep it up.

    # November 22 2010, 00:19

    cheapcar insurance United States said:

    This article is really resourceful, I actually stumbled upon this website not understanding i'd get this kind of wealthy content and knwoledge. I've also checked on other poss of yours and they had been fairly enlighten and educative. You actually did a nice job. Preserve it up.

    # November 22 2010, 03:21

    nyc dumpsters United States said:

    Hello thank you for the thoughtful post.   would it be ok to use your   piece in an upcoming article?   I will be happy to give you credit and hyperlink to this page.  Please let me know if i have your permission to do so. Thank you.

    # November 22 2010, 21:56

    haifa wehbe wedding United States said:

    If you're still on the fence: grab your favorite earphones, head down to a Best Buy and ask to plug them into a Zune then an iPod and see which one sounds better to you, and which interface makes you smile more. Then you'll know which is right for you.

    # November 23 2010, 00:34

    goldeneye cheats for wii United States said:

    Well, this was kind of boring but whatever.

    # November 23 2010, 04:10

    custom design yoga pants United States said:

    hi there from Delaware!  Just came across your blog.  Actually read your article, I'll pass it along!  Smile  Have a excellent day!

    # November 23 2010, 05:25

    night terrors United States said:

    It actually took some time for me to consider it.. When I used to examine night terrors I pictured something bad. When my son started having them for the very first time I was horrified!! Now I keep up with the latest news and researches in hopes to uncover an effective cure

    # November 23 2010, 07:32

    Tyson Guertin United States said:

    I would like to say thanks for the efforts you have made writing this post. You've enlightening for me. I have forwarded this to a friend of mine.

    # November 23 2010, 07:54

    kate middleton United States said:

    This one is an inspiration personally to discover out more concerning this topic. I need to confess your clarity widened my sentiments and I'll immediately snatch your feed to keep updated on every future blog posts you may possibly generate. You are worthy of many thanks regarding a job perfectly done!

    # November 23 2010, 08:49

    kate middleton United States said:

    This one is an inspiration personally to discover out more regarding this subject. I need to admit your clarity extended my sentiments as well as I will right now grab your rss feed to stay updated with every new articles you might make. You are worthy of thanks regarding a job perfectly done!

    # November 23 2010, 08:55

    clickbank United States said:

    I am just impressed by the way you handled this issue. It isn't frequently I find a web site along with amazing articles similar to the ones you have. I'll make a note of your website feed to keep up to date with your hereafter updates. Once again, I truely like what you've got on your site.

    # November 23 2010, 09:01

    clickbank United States said:

    I am just astounded by the way you handled this issue. It is not often I stumbled upon a site with  material similar to the ones you have. Let me make a note of your blog feed to keep up-to-date with your hereafter updates. Yet again, I truely like what you've got here.

    # November 23 2010, 09:02

    Theo Drisko United States said:

    Hi, Thank's! I'd like to share this right now!

    # November 23 2010, 10:14

    Moncler Coats United States said:

    back you up

    # November 23 2010, 10:22

    North Face Jackets On Sale United States said:

    Moderator’s opinion identifies with mine

    # November 23 2010, 10:28

    North Face Outlet United States said:

    strongly agree

    # November 23 2010, 10:31

    The North Face Outlet United States said:

    We are at one on this subject

    # November 23 2010, 12:12

    North Face Uk United States said:

    I couldn't agree more with the thread starter

    # November 23 2010, 12:29

    Uggs For Cheap United States said:

    Bump, bump up

    # November 23 2010, 12:32

    Ali Shealey United States said:

    I really like this, but I think you must be more carefull with the words bro.

    # November 23 2010, 15:38

    no download slots United States said:

    Great info.  You need a "tell-a-friend" button so I can send this to people.

    # November 24 2010, 04:42

    tim viec nhanh United States said:

    I was questioning what is up with that bizarre gravatar??? I know 5am is early and I'm not wanting my finest at that hour, however I hope I do not seem like this! I'd nonetheless make that face if I am requested to do a hundred pushups. lol  Anyway, in my language, there should not much good source like this.  

    # November 24 2010, 11:31

    Plus size boots United States said:

    Are you currently sick and tired with squeezing your curvy calves in to boots created for maybe 10% of the population? Don’t despair, we've gathered here the links to plenty of vendors who appreciate we come in many shapes and sizes and to be plus sized calf doesn’t mean you don’t have style or dollars to invest on fashion!

    # November 24 2010, 11:50

    latest sports news United States said:

    Right after making use of a whole cocktail of sports activities supplements, and reading the advice right here and on so several other blogs and sites, Ive come to your conclusion that I am completely puzzled.. could you please explain it far more? Thx

    # November 24 2010, 19:57

    Terri White United States said:

    Hi, I go through a lot of WordPress blogs on a regular schedule and countless blogs lack substance however, I simply wished to make a speedy comment to say FANTASTIC website! I'll be checking in often now.  Maintain the great job! Smile

    # November 24 2010, 20:08

    Kip Jax United States said:

    This post was a wonderful read. Thanks for the info.

    # November 24 2010, 20:09

    bachelorette party favors United States said:

    Do you have any videos on youtube?

    # November 24 2010, 20:18

    Julie Brown United States said:

    Hey, I read a lot of WordPress blog posts on a frequent schedule and numerous blogs don't have substance however, I just wished to make a quick remark to say FANTASTIC website! I am going to be stopping by on a regular basis now.  Keep up the great work! Smile

    # November 24 2010, 20:33

    Katie Anderson United States said:

    Hello, I read a lot of WordPress blog posts on a regular schedule and a lot of blogs lack real material however, I simply desired to make a quick comment to express GREAT blog! I'm going to be stopping by regularly now.  Continue the great work! Smile

    # November 24 2010, 20:40

    Emily White United States said:

    Hi, I read a lot of WordPress blogs on a regular basis and a lot of blogs lack real material although, I merely wanted to make a speedy comment to say GREAT weblog! I'm going to be stopping by on a regular basis now.  Keep up the good work! Smile

    # November 24 2010, 21:09

    Hello Kitty Purse United States said:

    Things you brought up seems sensible.  However, consider this, what happens if you offered a little bit more?  I am talking about, I don't tend to tell you how to run ur blog, however what if you actually added more stuff that can get people's particular attention?  Just simply like a video clip or maybe a snapshot or two to obtain your readers psyched regarding what you mentioned.

    # November 25 2010, 04:58

    pregnancy miracle United States said:

    I wanted to thank you for this amazing post .I definitely loved every little bit of it. I have you bookmarked your web site to see at the current stuff you post.

    # November 25 2010, 05:03

    Jacelyn Strickling United States said:

    Twitter had a tweet on  <a href="www.discountcomputerwarehouse.com/computer-systems-c-9.html"><b>Discount Computer Warehouse Computer Systems</b></a> that lead me hear for some reason. Not sure what this has to do with what I was searching for.

    # November 25 2010, 07:44

    Nicole Scherzinger (9) HD Wallpaper United States said:

    Where can i find your rss? I cant find it

    # November 25 2010, 09:34

    Joanne Barrow United States said:

    Have you ever considered writing an e-book or guest authoring on other websites? I have a blog centered on the same ideas you discuss and would really like to have you share some stories/information. I know my viewers would enjoy your work. If you are even remotely interested, feel free to shoot me an e mail.

    # November 25 2010, 13:18

    Buy cialis Online United States said:

    Erectile Dysfunction can be a result of various underlying factors. Diabetes, high blood pressure, cardio vascular diseases and other psychological issues can cause male impotence in men.

    # November 26 2010, 00:04

    omasex filme United States said:

    Hello you i do totally like your great site, I would feel very special if you would ask me to post a review on your fine site in this little Dining Site <a href="http://www.oma-chat-live.de/">http://www.oma-chat-live.de/</a> would you say yes? Thanks

    # November 26 2010, 03:24

    double chin United States said:

    Great stuff, really enjoyed it you can be sure that I'll be back!

    # November 26 2010, 04:24

    Facebook statuses United States said:

    Where can i find your rss? I cant find it

    # November 26 2010, 05:50

    Emo United States said:

    Where can i find your rss? I cant find it

    # November 26 2010, 10:31

    Compact refrigerator United States said:

    This site is cool. i visit here evaryday.

    # November 26 2010, 15:16

    MBRP Exhaust United States said:

    scooby dooby doo!

    # November 26 2010, 16:31

    porno izle United States said:

    In use, the Galaxy Tab performs well, but is not exemplary. It feels snappy enough, but longish load times can sometimes be tiresome, and webpages invariably loaded more slowly than the iPad — sometimes taking twice as long. We also ran into a few issues with apps hanging and the Wi-Fi connection suddenly vanishing without explanation. Reboots solved both issues.

    # November 26 2010, 17:06

    diets that work United States said:

    Thanks a lot for the information. I have been searching for this for awhile with Bing and it has been a real chore.

    # November 26 2010, 19:30

    Cross cutting shredder United States said:

    Hey check out my blog too. I hope i have some cool stuff too

    # November 26 2010, 20:09

    Zetta Slowik United States said:

    it appears that you’ve put lots of effort and work into your article and you want much more of using the net currently. I sincerely became a kick through your post. I don’t surely have much to speak about in response, I only tried to comment to response wonderful work..

    # November 26 2010, 20:45

    hemorrhoid treatment United States said:

    Keep up the great posts. I really like reading what you have to say. Thanks.

    # November 26 2010, 21:14

    male enhancement pills United States said:

    My first visit on this blog, nice article on this blog, except that the template in use is also attractive. if you have free time please visit my blog at http://penisenlargementworlds.com please comment on how do you think about my site.

    # November 27 2010, 00:18

    Nikon d3000 10mp digital slr camera with United States said:

    This site is great. i visit here evaryday.

    # November 27 2010, 01:13

    pregnancy miracle United States said:

    I preferred to thank you for this concerning paragraph .I definitely liked every little bit of it. I have you bookmarked your web site to see at the modern stuff you write.

    # November 27 2010, 02:20

    male enhancement pills United States said:

    My first visit on this blog, nice article on this blog, except that the template in use is also attractive. if you have free time please visit my blog at http://penisenlargementworlds.com please comment on how do you think about my site.

    # November 27 2010, 02:45

    Georgine Goney United States said:

    I completely adore reading your blog posts, the selection of articles are smashing.This blog was academic, I've needed to bookmark your site and subscribe to your feed in ifeed. Your theme appears lovely.

    # November 27 2010, 03:45

    MBRP Exhaust United States said:

    scooby dooby doo!

    # November 27 2010, 03:58

    Gebze United States said:

    Hi guys did you have old documents ? I applaud letter develop for my friend ... ..

    # November 27 2010, 04:11

    Wireless remote control and 57 full size tripod for nikon d3000 nikon d5000 digital slr camera United States said:

    Thanks for posting this. i really enjoyed reading this.

    # November 27 2010, 06:31

    Aishwarya Rai United States said:

    Good God... I have been looking for the solution everywhere. Heart felt thanks for putting up this article... You saved me lot of time.

    # November 27 2010, 06:58

    MBRP Exhaust United States said:

    scooby dooby doo!

    # November 27 2010, 07:21

    Leroy Bellman United States said:

    i love google.

    # November 27 2010, 09:29

    second car insurance United States said:

    I have been following this blog for sometime now glad to see more information on this subject.

    # November 27 2010, 09:44

    Candace Callow United States said:

    Twitter had a tweet on  <a href="www.discountsportsmanstore.com/airguns-accessories.html"><b>Discount Sportsman Store Airguns</b></a> that lead me hear for some reason. Not sure what this has to do with what I was searching for.

    # November 27 2010, 10:15

    Pregnancy pact trailer United States said:

    Thanks for posting this. i really had good time reading this.

    # November 27 2010, 11:55

    Carlie Rasco United States said:

    Electronic Cigarette is a good alternative choice of smoking and big think is that it does not any health risk.

    # November 27 2010, 12:58

    Bennie Gagliardo United States said:

    Interesting very interesting...

    # November 27 2010, 13:29

    Vapor Cigarette United States said:

    E-cigarette is best alternative for traditional cigarette.. It has less and no nicotine in it. you may adjust smoke and nicotine level in it..

    # November 27 2010, 14:19

    commercial insurance United States said:

    I have been following this blog for sometime now glad to see more information on this subject.

    # November 27 2010, 14:43

    blogga United States said:

    I will keep in mind the post while i reach always be as part of your boots and shoes.

    # November 27 2010, 15:13

    MBRP Exhaust United States said:

    scooby dooby doo!

    # November 27 2010, 16:31

    Moncler jackets United States said:

    strongly agree

    # November 27 2010, 17:28

    Moncler United States said:

    I'm with moderator all the way!

    # November 27 2010, 17:30

    Moncler outlet United States said:

    Moderator’s opinion identifies with mine

    # November 27 2010, 17:32

    UGG Australia outlet United States said:

    Bump, bump up

    # November 27 2010, 18:11

    Kelly Mannick United States said:

    I genuinely like your innovative angle that you have on the topic. Certainly wasn’t planning on this at the time I begun browsing for tips. Your ideas were totally simple to understand, so I pondered precisely why I hardly investigated at this in the past. Happy to find out that there’s an individual online that obviously understands exactly what she is talking about. Exceptional piece of work - Get the facts first. You can distort them later.  Mark Twain 1835 1910        

    # November 27 2010, 18:23

    Ugg Boots Sale United States said:

    I agree with the moderator completely

    # November 27 2010, 18:43

    Cheap UGG Boots UK United States said:

    I couldn't agree more with the thread starter

    # November 27 2010, 19:13

    tuyen dung United States said:

    I was questioning if you would be desirous about becoming a visitor poster on my blog? and in trade you would put a link the submit? Please let me know whenever you get a chance and I will ship you my contact details - thanks.  Anyway, in my language, there aren't a lot good supply like this.  

    # November 27 2010, 19:47

    viec lam online United States said:

    Daniel, yea I can see what you probably did there. I really favored that part, but hehe I am not that harsh like my dad with these things. He at all times tells me crazy stories back within the day and calls me a loser. I suppose it's time I transfer out of my dad and mom' basement LOL. Aaanyways, what about you? what does your dad think xD" Anyway, in my language, there will not be a lot good supply like this.  

    # November 27 2010, 19:56

    viec lam ke toan United States said:

    Have you ever thought of adding extra movies to your weblog posts to keep the readers more entertained? I imply I just read by way of the entire article of yours and it was quite good but since I'm extra of a visible learner,I found that to be more helpful well let me know the way it seems! I really like what you guys are at all times up too. Such intelligent work and reporting! Sustain the good works guys I've added you guys to my blogroll. This is a great article thanks for sharing this informative information.. I will go to your weblog regularly for some latest post.  Anyway, in my language, there will not be much good supply like this.  

    # November 27 2010, 19:56

    viec lam United States said:

    Daniel, yea I can see what you probably did there. I really favored that part, however hehe I am not that harsh like my dad with these things. He all the time tells me loopy stories again within the day and calls me a loser. I assume it is time I move out of my mother and father' basement LOL. Aaanyways, what about you? what does your dad think xD" Anyway, in my language, there will not be a lot good supply like this.  

    # November 27 2010, 19:56

    life insurance india United States said:

    Great info. Really enjoyed reading your blog posts.

    # November 27 2010, 21:24

    Kelly Parkhouse United States said:

    This is a good approach to what, for some, may be a controversial topic. Very well though out post. - I'm not afraid to die. I just don't want to be there when it happens. - Woody Allen Born 1935

    # November 27 2010, 23:43

    Joanie Mientka United States said:

    Great blog! I truly really like how it is simple on my eyes too as the details are well written. I am wondering how I may be notified whenever a brand new post continues to be produced. I have subscribed for your rss feed which must do the trick! have a good day!

    # November 28 2010, 00:36

    Leonila Tieger United States said:

    I wonder what Palin or Mccain would be doing better right now that Obama isn't. Perhaps my military and civilian friends in SK would be getting killed so that people can stroke their egos about American military power

    # November 28 2010, 01:25

    tim viec nhanh United States said:

    I was questioning in case you can be interested by changing into a guest poster on my weblog? and in exchange you could possibly put a hyperlink the post? Please let me know once you get an opportunity and I'll send you my contact details - thanks.  Anyway, in my language, there are not much good source like this.  

    # November 28 2010, 02:15

    tim viec ke toan United States said:

    I used to be wondering should you would be taken with becoming a guest poster on my blog? and in trade you could possibly put a hyperlink the put up? Please let me know once you get an opportunity and I will send you my contact particulars - thanks.  Anyway, in my language, there are not a lot good supply like this.  

    # November 28 2010, 02:17

    tim viec United States said:

    Well, that is my very first visit on your weblog! We're a group of volunteers and beginning a model new initiative in a group inside the same niche. Your weblog supplied us helpful data to work on. You might have carried out a marvellous job! Anyway, in my language, there are not much good supply like this.  

    # November 28 2010, 02:17

    tim viec nhanh United States said:

    Can I make a suggestion? I believe youve obtained one thing good here. But what for those who added a pair links to a page that backs up what youre saying? Or maybe you might give us something to have a look at, something that might connect what youre saying to something tangible? Just a suggestion. Anyway, in my language, there are usually not much good source like this.  

    # November 28 2010, 02:26

    Aweber United States said:

    You are a very smart person!

    # November 28 2010, 04:37

    Kelly Kennel United States said:

    Hey, found your site by accident doing a search on Google but I’ll definitely be coming back.  - How can I believe in God when only last week I got my tongue caught in the roller of an electric typewriter? - Woody Allen Born 1935

    # November 28 2010, 09:05

    quang cao google United States said:

    I've to say, I dont know if its the clashing colours or the unhealthy grammar, but this blog is hideous! I imply, I dont want to sound like a know-it-all or something, however may you will have possibly put slightly bit more effort into this subject. Its really interesting, however you dont characterize it properly in any respect, man.  Anyway, in my language, there aren't much good source like this.  

    # November 28 2010, 09:19

    quang ba website United States said:

    Have you ever ever thought of including extra movies to your blog posts to maintain the readers extra entertained? I imply I simply learn through the entire article of yours and it was quite good however since I am extra of a visual learner,I discovered that to be extra helpful well let me know the way it turns out! I really like what you guys are always up too. Such clever work and reporting! Keep up the nice works guys I've added you guys to my blogroll. It is a great article thanks for sharing this informative information.. I'll visit your blog repeatedly for some newest post.  Anyway, in my language, there are not a lot good source like this.  

    # November 28 2010, 09:22

    cong ty seo United States said:

    I used to be searching for crucial information on this subject. The knowledge was necessary as I am about to launch my own portal. Thanks for providing a lacking link in my business.  Anyway, in my language, there are usually not much good source like this.  

    # November 28 2010, 10:56

    tang thu hang United States said:

    Excellent learn, I simply passed this onto a colleague who was doing a little analysis on that. And he truly bought me lunch as a result of I found it for him smile So let me rephrase that: Thanks for lunch! Anyway, in my language, there aren't a lot good source like this.  

    # November 28 2010, 10:57

    Kelly Tenda United States said:

    Thanks for this information. Was doing a Google search and came across this blog. I liked it so much that I bookmarked it. Additionally, I will be coming back for more so be sure to keep posting! - What nerve. Not even a modicum of originality.  Samuel Goldwyn 1882 1974        

    # November 28 2010, 10:59

    seo top 10 United States said:

    I used to be wondering should you would be taken with becoming a guest poster on my blog? and in trade you could possibly put a hyperlink the put up? Please let me know once you get an opportunity and I will send you my contact particulars - thanks.  Anyway, in my language, there are not a lot good supply like this.  

    # November 28 2010, 10:59

    Liberty Pachla United States said:

    It's excellent webpage, I was looking for something like this

    # November 28 2010, 11:05

    Kelly Braunschweige United States said:

    Then again, the opposite could be true. - When we played softball, I'd steal second base, feel guilty and go back. - Woody Allen Born 1935

    # November 28 2010, 12:35

    Kelly Klun United States said:

    I love these blogs! I have created a website from where I will promote these sites. - The government is unresponsive to the needs of the little man. Under 5'7", it is impossible to get your congressman on the phone.  Woody Allen Born 1935        

    # November 28 2010, 15:12

    North Face Outlet United States said:

    I fully agree with the forum moderator

    # November 28 2010, 15:22

    Moncler jackets United States said:

    Moderator’s opinion identifies with mine

    # November 28 2010, 15:50

    Moncler United States said:

    I agree with the moderator completely

    # November 28 2010, 15:53

    Moncler outlet United States said:

    I'm going to bump the thread (up)

    # November 28 2010, 15:56

    Ugg Boots Sale United States said:

    I'm going to bump the thread (up)

    # November 28 2010, 15:59

    Cheap UGG Boots UK United States said:

    We are at one on this subject

    # November 28 2010, 16:02

    girls peeing United States said:

    This is such a fantastic resource that you are supplying and also you give it away for totally free. I take pleasure in seeing web sites that comprehend the worth of supplying a prime resource for cost-free. I really loved reading your post. Thanks!

    # November 28 2010, 16:55

    Glady Cummings United States said:

    Hello could I quote some of the insight here in this blog if I reference you with a link back to your site?

    # November 28 2010, 19:55

    internet marketing software United States said:

    Thanks for your data but I'm getting some issues seeing images.

    # November 28 2010, 20:00

    antivirus firewall software United States said:

    Very good post... I observed this via google, google ftw!

    # November 28 2010, 20:11

    Justin Public United States said:

    i love google.

    # November 28 2010, 20:19

    Delpha Rimel United States said:

    I would like to thank you for the efforts you have made in composing this article. I am going for the same best work from you in the future as well. In fact your fanciful writing abilities has prompted me to start my own blog now. Actually the blogging is spreading its wings rapidly. Your write up is a fine example of it.

    # November 28 2010, 22:39

    Zero Calorie Foods United States said:

    Eating low calorie food has helped me lose a lot of weight. That means a lot of vegetables. Which is fine for me because I like them.

    # November 28 2010, 23:22

    Kelly Reppell United States said:

    Hey extremely nice web log!! Man .. Beautiful .. Amazing .. I will bookmark your blog too get true feeds also -- - Bisexuality immediately doubles your chances for a date on Saturday night.  Woody Allen Born 1935        

    # November 28 2010, 23:23

    Raging Alcoholic United States said:

    The ladies in my group spent an hour talking on this subject last night. I've even gotten two emails about it today. It's a hot topic.

    # November 28 2010, 23:31

    Tattoos United States said:

    How much is too much tattooing. I used to drive a cab and tourists would comment on how nice people are and how many tats they had. I hadn't thought about it until then but, Portlander's do seem to get tats just to have them. I guess more ink = more better. Personally I don't think should get a tattoo of a turtle just because they went to Cancun on vacation. I think the tat should have more meaning. It is, however, good for business. Anyone have a differing idea. I'd be glad to hear it.

    # November 28 2010, 23:46

    .NET Team United States said:

    Love the blog here. Nice colors. I am definitely staying tuned to this one. Hope to see more.

    # November 29 2010, 00:57

    heart ring United States said:

    Hi thanks for posting this information, I am going to try something very the same so this post is useful. -Billy K.

    # November 29 2010, 01:37

    Maryln Minden United States said:

    i love google.

    # November 29 2010, 03:08

    Josue Partible United States said:

    Hello, im coming from Dream Treasure Rewards group. We provide Popular Rewards for Filling Out Online Surveys As well really being around for over 14 years and having good customer service to take care of our members, we are also acknowledge throughout the internet society for providing wonderful rewards. Not like many rewards web pages that provide you the world and fail miserably, my web site is known to provide some of the best rewards existing. Here are plenty of of the most excellent benefits you are able to earn when you finish our on line surveys: iPads, iPhones, Discount cupons, mp3 players and more cool stuff.

    # November 29 2010, 03:25

    pandora uk United States said:

    I just couldnt leave your website before saying that I really enjoyed the quality information you offer to your visitors… Will be back often to check up on new stuff you post!

    # November 29 2010, 09:10

    Wenona Mcpartlin United States said:

    i love google.

    # November 29 2010, 09:36

    After Effects plugins United States said:

    Hello! Can I  pics from your webpage for my PC wallpapper?

    # November 29 2010, 09:41

    espresso parts United States said:

    Hello, I found your blog in a new directory of blogs. I dont know how your blog came up, must have

    # November 29 2010, 10:33

    Iohn Gostigo United States said:

    This is the first time I have come across your site.  Post info, I'm sure I'll be back again.  Thanks!

    # November 29 2010, 10:39

    waste pumps for sale United States said:

    Makes a change to read a post where someone knows what they are talking about.

    # November 29 2010, 11:57

    liquid diet United States said:

    This is getting a bit more interesting after reading again, but I'm not quite sure that this is what I'm looking for. But thanks mate!

    # November 29 2010, 12:06

    James @ How to overclock cpu guide United States said:

    Cheers! As it goes I'm currently on the rampage for this kinda stuff at the mo... James

    # November 29 2010, 12:24

    holland america cruises 2011 United States said:

    Hi, I can’t figure out how to add your site in my rss reader. Can you tell me what I'm doing wrong, please.

    # November 29 2010, 15:35

    Nikon D3100 United States said:

    interesting, i am bookmarking that.

    # November 29 2010, 17:09

    auto insurance companies United States said:

    How to get cheap insurance. www.flipxinsure.com

    # November 29 2010, 17:13

    amusement park sex United States said:

    Very nice post and straight to the point. I am not sure if this is actually the best place to ask but do you folks have any thoughts on where to get some professional writers? Thanks Smile

    # November 29 2010, 18:06

    child and women abuse United States said:

    Such a usefule blog…wow !!!!

    # November 29 2010, 18:46

    James @ How to overclock cpu guide United States said:

    Cheers! As it goes I'm currently on the rampage for this kinda stuff at the mo... James

    # November 29 2010, 18:54

    MBRP Exhaust United States said:

    scooby dooby doo!

    # November 29 2010, 21:12

    Garth Rozon United States said:

    i love google.

    # November 29 2010, 22:44

    Carnival Cruises 2011 United States said:

    I am constantly searching for good info on this topic. It can be difficult to find sometimes. Thanks!. I will check back on your site from time to time to see what else you have to offer.

    # November 29 2010, 23:51

    Holland America Cruises 2011 United States said:

    I am always searching for good information on this topic. It can be hard to locate sometimes. Thanks!. I will check back on your site from time to time for more information.

    # November 29 2010, 23:56