1 /***************************************************************************
3 Copyright (c) Microsoft Corporation. All rights reserved.
4 This code is licensed under the Visual Studio SDK license terms.
5 THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
10 ***************************************************************************/
13 using System
.ComponentModel
.Design
;
14 using System
.Diagnostics
;
16 using Microsoft
.VisualStudio
.Shell
;
17 using Microsoft
.Samples
.VisualStudio
.Services
.Interfaces
;
19 namespace Microsoft
.Samples
.VisualStudio
.Services
22 /// This is the package that exposes the Visual Studio services.
23 /// In order to expose a service a package must implement the IServiceProvider interface (the one
24 /// defined in the Microsoft.VisualStudio.OLE.Interop.dll interop assembly, not the one defined in the
25 /// .NET Framework) and notify the shell that it is exposing the services.
26 /// The implementation of the interface can be somewhat difficult and error prone because it is not
27 /// designed for managed clients, but using the Managed Package Framework (MPF) we don’t really need
28 /// to write any code: if our package derives from the Package class, then it will get for free the
29 /// implementation of IServiceProvider from the base class.
30 /// The notification to the shell about the exported service is done using the IProfferService interface
31 /// exposed by the SProfferService service; this service keeps a list of the services exposed globally
32 /// by the loaded packages and allows the shell to find the service even if the service provider that
33 /// exposes it is not inside the currently active chain of providers. Register the service and package
34 /// inside the services section of the registry, the service will available for all clients. VS will
35 /// automatically load the package when the service is requested. The MPF exposes the
36 /// ProvideServiceAttribute registration attribute to add the information needed inside the registry,
37 /// so that all we have to do is to use it in the definition of the class that implements the package.
39 // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
41 [PackageRegistration(UseManagedResourcesOnly
= true)]
42 // This attribute is used to register the informations needed to show the this package
43 // in the Help/About dialog of Visual Studio.
44 [InstalledProductRegistration("#112", "#113", "1.0", IconResourceID
= 400)]
45 [ProvideService(typeof(SMyGlobalService
))]
46 [System
.Runtime
.InteropServices
.Guid(GuidsList
.guidSevicesPkgString
)]
47 public sealed class ServicesPackage
: Package
50 /// Standard constructor for the package.
52 public ServicesPackage()
54 // Here we update the list of the provided services with the ones specific for this package.
55 // Notice that we set to true the boolean flag about the service promotion for the global:
56 // to promote the service is actually to proffer it globally using the SProfferService service.
57 // For performance reasons we don’t want to instantiate the services now, but only when and
58 // if some client asks for them, so we here define only the type of the service and a function
59 // that will be called the first time the package will receive a request for the service.
60 // This callback function is the one responsible for creating the instance of the service
62 IServiceContainer serviceContainer
= this;
63 /// <param name="promote"> a 'true' boolean value promotes this request to any parent service
64 /// containers </param>
65 serviceContainer
.AddService(typeof(SMyGlobalService
), CreateService
, true);
66 serviceContainer
.AddService(typeof(SMyLocalService
), CreateService
);
70 /// This is the function that will create a new instance of the services the first time a client
71 /// will ask for a specific service type. It is called by the base class's implementation of
74 /// <param name="container">The IServiceContainer that needs a new instance of the service.
75 /// This must be this package.</param>
76 /// <param name="serviceType">The type of service to create.</param>
77 /// <returns>The instance of the service.</returns>
78 private object CreateService(IServiceContainer container
, Type serviceType
)
80 // Check if the IServiceContainer is this package.
81 if (container
!= this)
83 Debug
.WriteLine("ServicesPackage.CreateService called from an unexpected service container.");
87 // Find the type of the requested service and create it.
88 if (typeof(SMyGlobalService
).IsEquivalentTo(serviceType
))
90 // Build the global service using this package as its service provider.
91 return new MyGlobalService(this);
93 if (typeof(SMyLocalService
).IsEquivalentTo(serviceType
))
95 // Build the local service using this package as its service provider.
96 return new MyLocalService(this);
99 // If we are here the service type is unknown, so write a message on the debug output
101 Debug
.WriteLine("ServicesPackage.CreateService called for an unknown service type.");