Dotneteers.net
All for .net, .net for all!

LearnVSXNow! #26 - Services — with no-code service initialization

In the LearnVSXNow series I treated Visual Studio Services several times. In Part #5 (Basic VSX Ideas), I dealt with the basic concepts of services. In Part #9 (Refactoring to a Service) I shared some ideas about how to create and use a global service. I have also written a “deep dive” about the VS SDK’s Service Reference Sample.

During that work I have collected some useful information about how VSPackages handle services. I also used in this knowledge to build some new types into the VSXtra project to help creating and using VS services in a declarative way.

In this article I share you what I have learnt and also present my imagination about how service declaration can be done better than in the current MPF.

Services in VSPackages

In order VSPackages (even from separate developers or manufacturers) can communicate with each others, they must define a contract. Services in VS Packages are the implementations of these contracts. When a package wants to use a function by a specific contract, it requests for a service object to invoke the function.

VSPackages that have services are called service provider packages. Services that are provided in order other VSPackages can consume them are called global services. A package can have services that are used only from within the package itself or its consumers are the objects created by the service. This kind of service is called local service.

Global services play a crucial role in Visual Studio Extensibility. A large part of functions of the Visual Studio IDE (like writing to the activity log, sending messages to an output window pane, getting the root DTE object of the automation object hierarchy, using common UI functions and many more) are accessible through global services. When you create a global service you make it explicitly to be available and consumed by other packages. For example, if you have a service that reformats your code files according to a set of options you make it global in order to other packages can reformat source files.

You may ask why to have local services at all? Do not believe local services are unnecessary! One reason of having them is just to break up a large amount of code (a package) into logically decoupled chunks that can managed in an easier and more straightforward way. Other reason is intercepting a global service. For example in case of code reformatting service you may provide a way (a service) to push formatting options and methods (e.g. how to tear a long string literal into lines) into the global formatting service. You can create a local service for this purpose and plug it into the global service in order it can use it.

Packages can expose services by implementing the IServiceProvider interface of the Microsoft.VisualStudio.OLE.Interop namespace (do not mix it with the IServiceProvider type of System.ComponentModel!). The Package class of the Managed Package Framework implements this interface, so we get it free.

VS SDK’s Services Reference Sample

The Service Reference Sample shipped with VS SDK is a small but pretty well structured solution to demonstrate how to create and consume global and local services. After you build and run the sample, it adds three new items to the Tools menu:


Each menu function does a little work; they simply send a message to the Output window:

The sample itself contains two assemblies:

—  A contract assembly defining the interface of the services

—  Another assembly containing a service package (this package owns the objects implementing the services) and a client package to demonstrate using the services

Service contract

The contract assembly defines the global service interface in this way:

[Guid("ba9fe7a3-e216-424e-87f9-dee001228d03")]

[ComVisible(true)]

public interface IMyGlobalService

{

  void GlobalServiceFunction();

  int CallLocalService();

}

 

[Guid("fafafdfb-60f3-47e4-b38c-1bae05b44240")]

public interface SMyGlobalService

{

}

The service follows the service design pattern recommended by the VS SDK. By this pattern we use two interfaces for a service: the first interface is the one defining the service contract. This interface is COM visible in order to be available by external packages. The other interface type is actually the “address” of the service. We can use this interface type as the parameter of the GetService method (we’ll see it from closer soon) when requesting a service object.

Both interface types have an explicit GUID that can be used by other (unmanaged) packages to address and access the service. IMyGlobalService defines two methods: GlobalServiceFunction and CallLocalService are service methods accessible globally; the latter one also invokes a local service method. SMyGlobalService is a markup interface; its only role is to provide the “address” for the service object implementing the IMyGlobalService. Since the VS Shell uses COM technology behind the scenes, IMyGlobalService must be visible by other COM objects.

At the end of the day all service objects are used as COM objects, their consumers look them as COM object instances. Because of this fact you must use COM compliant types representing your services. The main point you have to take care about is the differences in lifecycle management of .NET and COM. While .NET uses a garbage collection mechanism, COM uses reference counting: you must explicitly tell when you release a reference to a COM object in order resources held by it can be reclaimed when the counter reaches zero. When your services consume native COM objects, you must manage their lifecycle by your own implementing the IDisposable interface.

Detailing creation of COM compliant types is beyond the scope of this article. A good start is to look for the reference documentation of the Marshal class of the System.Runtime.InteropServices namespace.

Should you be hundred percent sure that your service will be used only by managed clients (packages or add-ins) you can use any managed type in the service code.

IMyLocalService follows exactly the same pattern as IMyGlobalService.

Contract assembly

The Reference.Services.Interface project represent the contract assembly that is by its nature a tiny assembly with two files: IMyGlobalService.cs and IMyLocalService.cs representing contract types for global and local services respectively. This assembly has no direct relation with VS: you can see that it references only the standard .NET system assemblies.

This example puts not only the global but the local service definition into the contract assembly. You do not need to put your local services’ contract definition in a contract assembly if those are not used outside of your package. Do not forget, you may use a local service outside of its implementing package, for example if it is used to intercept a global service. It is always a good practice to put service definitions available outside of your package into a contract assembly.

Service implementation

The VS SDK pattern for service definition cannot be complete without the service implementation. The implementation of services can be found in the same project (Services.Reference) as the demonstration packages. Of course, this project references the Services.Reference.Interfaces project in order to access the contract definitions. The MyGlobalService.cs contains the global service implementation:

public class MyGlobalService : IMyGlobalService, SMyGlobalService

{

  private IServiceProvider serviceProvider;

  public MyGlobalService(IServiceProvider sp)

  {

    Trace.WriteLine("Constructing MyGlobalService");

    serviceProvider = sp;

  }

 

  public void GlobalServiceFunction()

  {

    string outputText = " ====================================== " +

                        "\tGlobalServiceFunction called. " +

                        " ====================================== ";

    HelperFunctions.WriteOnOutputWindow(serviceProvider, outputText);

  }

 

  public int CallLocalService()

  {

    IMyLocalService localService = serviceProvider.

      GetService(typeof(SMyLocalService)) as IMyLocalService;

    if (null == localService)

    {

      Trace.WriteLine("Cannot get local service from global one.");

      return -1;

    }

    return localService.LocalServiceFunction();

  }

}

The service class implements both the contract interface (IMyGlobalService) and the “address” interface (SMyGlobalService). Implementation of the GlobalServiceFunction is straightforward; in the CallLocalService method we can see how to address and obtain a service object reference for the local service by using the GetService method.

Service initialization

Visual Studio Extensibility uses the concept of service containers to obtain requested services. IServiceContainer represents this idea in VSX by extending IServiceProvider with AddService and RemoveService methods (IServiceProvider is the interface representing the GetService method). The Visual Studio IDE is a service container and the Package class of the MPF implements IServiceContainer, so it is also a service container.

Service containers are designed so that they can promote services to their parent containers and this can be propagated through the chain of containers. Also service revocation can be optionally propagated through the container chain.

Containers can register either concrete service instances for a service of a given type or a callback method that creates the instance just in time when it is (first) requested. This pattern allows deferring the creation of resource-expensive service objects to the moment they need to be used.

The key method of obtaining service instances is GetService. This is implemented in the Package class so that first it looks up the service in the container of the package. If the service is found there, the corresponding object is returned. In the other case GetService asks the parent service container (that is the IDE’s container) and the service object is returned from there. If the service cannot be found in any containers, a null reference is returned. The Package implementation adds a few services (IMenuCommandService and IOleCommandTarget) to the package’s container during service construction time.

In order to be able to get service objects by GetService, those objects should be initialized. The code for this can be found in the ServicesPackage.cs file:

[DefaultRegistryRoot(@"Microsoft\VisualStudio\9.0Exp")]

[PackageRegistration(UseManagedResourcesOnly = true)]

[ProvideService(typeof(SMyGlobalService))]

[System.Runtime.InteropServices.Guid("...")]

public sealed class ServicesPackage : Package

{

  public ServicesPackage()

  {

    IServiceContainer serviceContainer = this as IServiceContainer;

    ServiceCreatorCallback callback =

      new ServiceCreatorCallback(CreateService);

        serviceContainer.AddService(typeof(SMyGlobalService),

      callback, true);

        serviceContainer.AddService(typeof(SMyLocalService), callback);

  }

 

  private object CreateService(IServiceContainer container,

    Type serviceType)

  {

    if (container != this)

    {

      Trace.WriteLine("Unexpected service container.");

      return null;

    }

    if (typeof(SMyGlobalService) == serviceType)

    {

      return new MyGlobalService(this);

    }

    if (typeof(SMyLocalService) == serviceType)

    {

      return new MyLocalService(this);

    }

    Trace.WriteLine("Unknown service type.");

    return null;

  }

}

Packages are on-demand loaded and so service information should be registered in order the VS Shell be aware of it without loading the package. This is the role of the ProvideService attribute.

The CreateService method creates the service object when it is requested first time. Any subsequent service request calls will return the same service instance. The AddService method of the IServiceContainer is used to add service declarations to the container. The true value of the third parameter of the first AddService method signs that the service is intended to be added to the parent service container (it is a global service).

As a result of the service initialization, service containers store the information as it is illustrated here:


Within your package you can follow the same pattern to create objects with their own service containers by implementing IServiceContainer. In this case you can establish a deeper hierarchy of containers. Following the pattern, you should first look up a service in the closest container you are associated with and then you can go up in the hierarchy of containers while you reach the global container.

Service Invocation

ClientPackage is a small package that simply calls methods bound to the new menu items on the Tools menu. All three methods (GetGlobalServiceCallback, GetLocalServiceCallback and GetLocalUsingGlobalCallback) use GetService to obtain service object references.

GetLocalServiceCallback tries to obtain a reference to SMyLocalService. Because SMyLocalService cannot be found either in ClientPackage’s service container or in the global service container, no service instance will be retrieved. GetGlobalServiceCallback cannot find SMyGlobalService in ClientPackage’s service container but it definitely finds it in the global service container. The nice thing demonstrating the role of service containers is the fact the GetLocalUsingGlobalCallback called from ClientPackage is able to obtain both services as its source code indicates:

// --- ClientPackage.cs:

private void GetLocalUsingGlobalCallback(object sender, EventArgs args)

{

  IMyGlobalService service = GetService(typeof(SMyGlobalService))

    as IMyGlobalService;

  if (null == service)

  {

    Trace.WriteLine("Can not get the global service.");

    return;

  }

  service.CallLocalService();

}

 

// --- MyGlobalService.cs:

public int CallLocalService()

{

  IMyLocalService localService = 

    serviceProvider.GetService(typeof(SMyLocalService))

    as IMyLocalService;

  if (null == localService)

  {

    Trace.WriteLine("Can not get the local service from the global one.");

    return -1;

  }

  return localService.LocalServiceFunction();

}

First it finds SMyGlobalService in the global service container. Because the service object is in the ServicesPackage, the GetServiceMethod call in CallLocalService looks up the service container of ServicePackage and finds SMyLocalService there.

Using VSXtra for Services

I like the service pattern used in Visual Studio. It is great and allows packages to interact with each other through services. However, when I create my own services, I have to write many code lines dealing with service initialization, especially when the “lazy” service object instantiation is used.

To make the life easier, I created a declarative pattern for service definition and initialization. In this part of the article I’d like to show you this pattern. I will implement the functionality of VS SDK’s Services Reference Sample. I created only one assembly; I use this to hold both the ServicesPackage and ClientPackage. In my implementation I did not separate the service contracts into a separate assembly.

Service package and service declaration

The package declaration is simple; there is no direct code for service initialization:

[PackageRegistration(UseManagedResourcesOnly = true)]

[DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]

[ProvideService(typeof(SMyGlobalService))]

[Guid(GuidList.guidServicesPkgString)]

public sealed class ServicesPackage : PackageBase

{

}

The PackageBase class contains the implementation that recognizes services to be initialized (we have MyGlobalService and MyLocalService) and even promotes the SMyGlobalService to the parent service container (VS Shell’s service container). How does PackageBase know which objects represent services and how to handle them? The key is the service class declaration:

[Promote]

public class MyGlobalService :

    VsxService<ServicesPackage, SMyGlobalService>,

    IMyGlobalService

{

  // --- Service body omitted

}

 

[AutoCreateService]

public class MyLocalService :

  VsxService<ServicesPackage, SMyLocalService>,

  IMyLocalService

{

  // --- Service body omitted

}

The VsxService<TPackage, TService> generic class declares a service “addressed” with the TService type and owned by the package of type TPackage. By defining the package type in the first type parameter allows the service body to access the package’s service provider. The second type parameter defines the “address” that is used during service initialization to allow the package retrieve the right service object with the GetService call.

If your service already has a base class and so you cannot derive it from VsxService<,> you can implement the IVsxService<,> markup interface. PackageBase scans the package assembly for types implementing IVsxService<,> and initializes them according to the attributes attached to the service class.

MyGlobalService uses the Promote attribute that signs the service should be promoted to the parent container (so it is a global service). MyLocalService uses the AutoCreateService attribute to instruct PackageBase to automatically create a service instance during registration. As a result of the declarations above, MyGlobalService is promoted to become a global service and is instantiated at the first time when the service is requested. MyLocalService stays local and is instantiated as soon as the package is loaded.

Service implementation

By using the declaration constructs above, service bodies get a bit simpler:

[Promote]

public class MyGlobalService :

  VsxService<ServicesPackage, SMyGlobalService>,

  IMyGlobalService

{

  public void GlobalServiceFunction()

  {

    var outputText = " ====================================== " +

                     "\tGlobalServiceFunction called. " +

                     " ====================================== ";

    OutputWindow.General.WriteLine(outputText);

  }

 

  public int CallLocalService()

  {

    var localService =

    ServiceProvider.GetService<SMyLocalService, IMyLocalService>();

    if (null == localService)

    {

      OutputWindow.Debug.WriteLine("Can not get the local service.");

      return -1;

    }

 

    return localService.LocalServiceFunction();

  }

}

By deriving our class from VsxService<,> we have a ServiceProvider property “for free” and can use the related package’s GetService method. The original sample uses the services with a constructor where the package’s service provider is passed as an argument. With VSXtra, there is no need to write this code.

By the way, I’d like to say thank you to Pablo Galiano who used the generic GetService method pattern above in his PowerCommands package, I find it great, so use it in VSXtra.

MyLocalService implementation is also simple:

[AutoCreateService]

public class MyLocalService :

  VsxService<ServicesPackage, SMyLocalService>,

  IMyLocalService

{

  public int LocalServiceFunction()

  {

    var outputText = " ====================================== " +

                     "\tLocalServiceFunction called. " +

                     " ====================================== ";

    OutputWindow.General.WriteLine(outputText);

    return 0;

  }

}

Where we are?

Services use the concept of service containers to provide access to the requested service through the GetService method. During the package initialization time the services defined in the VSPackage should be registered with the appropriate service containers using the IServiceContainer’s AddService method.

VSXtra uses a declarative approach to allow service registration with no-code.


Posted Jul 23 2008, 08:05 AM by inovak
Filed under:

Comments

Visual Studio Hacks wrote Visual Studio Links #56
on Wed, Jul 23 2008 19:44

My latest in a series of the weekly, or more often, summary of interesting links I come across related to Visual Studio. Lisa Feigenbaum is looking for feedback on a potential Call Hierarchy feature on The Visual Basic Team blog. Visual Studio 2008 KB

Recent Links Tagged With "localservice" - JabberTags wrote Recent Links Tagged With "localservice" - JabberTags
on Thu, Apr 16 2009 6:04

Pingback from  Recent Links Tagged With "localservice" - JabberTags

New Jersey DWI Lawyer wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sun, Feb 10 2013 23:13

Im obliged for the post. Really Cool.

kanvas tablo wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Mon, Feb 11 2013 9:13

Really enjoyed this blog article. Will read on...

ereleases article wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Mon, Feb 11 2013 9:26

Major thanks for the article post.

Topsoil Supplies wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Feb 16 2013 13:42

Thanks a lot for the article.Thanks Again.

hgh review wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Mon, Feb 18 2013 6:26

My brother recommended I might like this website. He was entirely right. This post actually made my day. You can not imagine simply how much time I had spent for this information! Thanks!

buy stendra generic wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Feb 23 2013 19:06

9mD5Tn I cannot thank you enough for the article.Much thanks again. Really Great.

best way to get more twitter followers wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Tue, Feb 26 2013 19:49

I really enjoy the blog.Really thank you! Much obliged.

how to make hair grow faster wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Tue, Feb 26 2013 21:31

Very informative article post.Really looking forward to read more.

seo search engine wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Tue, Feb 26 2013 22:51

I appreciate you sharing this blog post.Really looking forward to read more. Cool.

get paid to be an extra wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Tue, Feb 26 2013 23:09

Say, you got a nice blog article. Cool.

Company Names wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Tue, Feb 26 2013 23:35

Thank you for your article post.Really looking forward to read more. Keep writing.

Best Priced Home Audio and Video wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 0:44

I really enjoy the post.

instagram selena gomez wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 0:44

Really informative blog.Thanks Again. Cool.

colonie de vacances wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 1:27

I loved your blog post. Fantastic.

vagas no rio wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 2:18

Really appreciate you sharing this article. Fantastic.

buy real instagram followers wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 2:36

I think this is a real great article post. Keep writing.

empower network blogging wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 3:20

I really enjoy the article post. Awesome.

buy a property wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 3:56

Really enjoyed this post.Really thank you! Awesome.

kim kardashian ethnicity wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 4:29

Major thankies for the article post. Fantastic.

Kardashian wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 5:13

I truly appreciate this blog.Really looking forward to read more.

photography book wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 5:35

I loved your post.Much thanks again. Cool.

real instagram followers free wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 6:22

Thanks-a-mundo for the article.Really looking forward to read more. Fantastic.

marketing secrets wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 7:14

Awesome blog post.Really thank you! Really Great.

how to get likes on instagram tags wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 8:18

I think this is a real great post.Thanks Again.

nikon d3200 price in chennai wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 8:53

Very good post.Thanks Again. Cool.

idaniko varos wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 10:33

Very good post.Much thanks again. Much obliged.

walmart camera wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 11:02

Hey, thanks for the blog post. Really Cool.

kerala hotels wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 12:11

I value the blog article.Thanks Again. Cool.

facebook photo likes wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 12:13

Great, thanks for sharing this blog post.Really looking forward to read more. Awesome.

create free blog wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 14:06

wow, awesome post.Really looking forward to read more. Much obliged.

sbobet wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 14:52

I cannot thank you enough for the blog article.Really thank you!

roofing dallas wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 16:01

Say, you got a nice blog article.Really thank you! Cool.

oil painting sale wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 19:54

This is one awesome blog post.Really thank you! Keep writing.

new york pianists wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Wed, Feb 27 2013 22:44

Very good blog post.Thanks Again. Cool.

barrel sauna wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Thu, Feb 28 2013 7:56

Hey, thanks for the blog post. Great.

clomid no prescription wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Thu, Feb 28 2013 17:18

MR7nuD Im obliged for the post.Really thank you! Fantastic.

Vpn wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Thu, Feb 28 2013 20:46

Appreciate you sharing, great blog post.Really looking forward to read more. Will read on...

ourmeds wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Thu, Feb 28 2013 22:21

I cannot thank you enough for the article.Much thanks again. Keep writing.

Anadolu jet ucak bileti|Anadolu jet ucak bileti wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 12:34

Looking forward to reading more. Great article.Much thanks again. Really Cool.

GeForce GTX 690 wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 12:47

This is one awesome blog post.Really looking forward to read more. Want more.

escorts wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 14:22

Really appreciate you sharing this blog article.Really thank you! Cool.

spectacole pirotehnice wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 14:37

A round of applause for your post.Much thanks again.

wien galerien wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 15:27

Enjoyed every bit of your blog article. Want more.

adjustable dumbbells wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 15:58

A big thank you for your article post.Really thank you! Keep writing.

article writing software wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 17:29

Wow, great blog post.Much thanks again. Much obliged.

social bookmarking wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 17:31

I truly appreciate this article.Much thanks again. Will read on...

steals and deals wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 17:33

I really liked your article post.Thanks Again. Cool.

make money online wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 19:09

Thanks so much for the article post.Really thank you! Awesome.

guinness storehouse free entry wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 19:14

I truly appreciate this blog.Thanks Again. Want more.

how to light video wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 19:37

Thank you for your article post.Thanks Again. Cool.

ekg blog wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 20:59

Wow, great article.Really thank you! Awesome.

Multilevell marketing wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 21:42

wow, awesome article.Really looking forward to read more. Cool.

watch here wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 22:23

Im obliged for the blog article.Much thanks again. Want more.

Ferienwohnung cuxhaven wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 22:41

Thanks again for the post. Cool.

website wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Fri, Mar 1 2013 23:46

Thanks for sharing, this is a fantastic blog.Really looking forward to read more. Much obliged.

halovar wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 0:24

Very good blog article.Really thank you! Much obliged.

Bacelo Hotels reservation wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 0:28

Really enjoyed this blog article. Keep writing.

real casanova wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 1:53

A big thank you for your post.Thanks Again. Want more.

oxyelite wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 2:09

Great article.Thanks Again. Want more.

lipo 6 wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 3:52

Great post.Much thanks again. Great.

fertility pharmacy wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 4:37

Very informative blog.Much thanks again. Will read on...

how to website wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 5:36

Enjoyed every bit of your article.Really looking forward to read more. Great.

car insurance wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 7:20

Thanks-a-mundo for the article post. Really Cool.

photo recovery wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 8:45

Great article post.Much thanks again.

90 Day Payday Loans wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 9:04

Hey, thanks for the blog article.Really looking forward to read more.

die cut machine wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 10:51

Thanks for the blog post. Really Great.

seo services adelaide wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 10:51

Wow, great blog article.Thanks Again. Great.

gold buyers wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 12:38

I think this is a real great blog article. Fantastic.

Get Twitter followers wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 13:18

Great, thanks for sharing this post.Really looking forward to read more. Much obliged.

Domain Names wrote re: LearnVSXNow! #26 - Services — with no-code service initialization
on Sat, Mar 2 2013 14:56

Hey, thanks for the blog post.Thanks Again. Really Cool.