Sign In
Kanwaljeet Singla's Weblog
Translate This Page
Translate this page
Powered by
Microsoft® Translator
Options
Blog Home
About
Email Blog Author
Share this
RSS for posts
Atom
RSS for comments
Search
Advanced search options...
Search In:
Everything
Blogs
Forums
People
Groups
Places
Pages
Date range:
All Time
Last Year
Last 6 Months
Last 3 Months
Last Month
Last Week
Last Two Days
Tags
AdvancedLogging
Appcmd
Configuration
Custom Errors
FastCGI
IIS 7.5
IIS7
MSDeploy
PHP
Tracing
WinCache
Archive
Archives
October 2009
(1)
September 2009
(2)
April 2009
(3)
March 2009
(1)
February 2009
(1)
January 2009
(2)
December 2008
(2)
June 2008
(3)
February 2008
(2)
December 2007
(2)
July 2007
(2)
June 2007
(1)
May 2007
(2)
April 2007
(1)
February 2007
(2)
December 2006
(2)
November 2006
(2)
August 2006
(3)
June 2006
(3)
Using IMetadataInfo::GetModuleContextContainer to store configuration data
MSDN Blogs
>
Kanwaljeet Singla's Weblog
>
Using IMetadataInfo::GetModuleContextContainer to store configuration data
Using IMetadataInfo::GetModuleContextContainer to store configuration data
Kanwaljeet Singla
21 Dec 2008 11:39 PM
Comments
0
If you write an IIS7 module, you would typically want to control its behavior based on some configuration data. IIS7 makes it really easy for developers to extend configuration schema so that their customers can put configuration data for their modules with other IIS configuration in
applicationHost.config
and
web.config
. Native module developers can then use AhAdmin APIs to read this configuration data. Reading configuration data for each request can be expensive. Developers would typically think of improving the performance by reading the configuration data once and then keeping the data in memory which can be used for other requests. To do this right, you need to worry about following things.
Keep unique data only for the paths where configuration changes and not for all possible configuration paths.
Detect configuration changes so that module always behave as per the latest configuration.
Only delete the configuration data of paths which are affected by the change and not throw everything.
Make sure this configuration store is accessed in thread safe manner.
Instead of implementing this from scratch, you can use IMetadata interface available in httpserv.h. Call IHttpContext::GetMetadata() to get IMetadata object which is different for each unique configuration path and then use the IMetadataInfo::GetModuleContextContainer()->SetModuleContext() to store any data you like for your module. Configuration data is a perfect example of kind of data you would like to store for a unique configuration path. Stored data can be retrieved using IMetadataInfo::GetModuleContextContainer()->GetModuleContext(). In addition to making sure that a unique metadata object is available only for paths where configuration changes, IIS will also take care of deleting proper stored contexts when a change notification arrives. Here is how doing this will look like in code.
//
// Globals
//
HTTP_MODULE_ID g_pModuleContext = NULL;
IHttpServer *
g_pGlobalInfo
= NULL;
HRESULT
WINAPI
RegisterModule(
DWORD
dwServerVersion,
IHttpModuleRegistrationInfo *
pModuleInfo,
IHttpServer *
pGlobalInfo
)
{
...
g_pGlobalInfo
= pGlobalInfo;
g_pModuleContext = pModuleInfo->GetId( );
...
}
class
MODULE_CONFIG :
public
IHttpStoredContext
{
public
:
//
// Always call this method to get configuration data
//
static
HRESULT
GetModuleConfig(
IHttpContext *
pContext,
MODULE_CONFIG ** ppModuleConfig
);
HRESULT
Initialize(
IHttpContext * pContext
);
// virtual
VOID
CleanupStoredContext(
VOID
)
{
delete
this
;
}
//
// Stored Configuration Data
//
};
//static
HRESULT
MODULE_CONFIG::GetModuleConfig(
IHttpContext *
pContext,
MODULE_CONFIG ** ppModuleConfig
)
{
HRESULT
hr
= S_OK;
MODULE_CONFIG *
pModuleConfig = NULL;
IHttpModuleContextContainer * pMetadataContainer = NULL;
pMetadataContainer = pContext->GetMetadata()->GetModuleContextContainer();
pModuleConfig = (MODULE_CONFIG *)pMetadataContainer->GetModuleContext( g_pModuleContext );
if
( pModuleConfig != NULL )
{
//
// We found stored data for this module for the metadata
// object which is different for unique configuration path
//
*ppModuleConfig = pModuleConfig;
return
S_OK;
}
//
// If we reach here, that means this is first request or first
// request after a configuration change IIS core will throw stored context
// if a change notification arrives for this metadata path
//
pModuleConfig =
new
MODULE_CONFIG();
if
( pModuleConfig == NULL )
{
return
E_OUTOFMEMORY;
}
//
// Read module configuration data and store in MODULE_CONFIG
//
hr = pModuleConfig->Initialize( pContext );
if
( FAILED( hr ) )
{
pModuleConfig->CleanupStoredContext();
pModuleConfig = NULL;
return
hr;
}
//
// Store MODULE_CONFIG data as metadata stored context
//
hr = pMetadataContainer->SetModuleContext( pModuleConfig,
g_pModuleContext );
if
( FAILED( hr ) )
{
pModuleConfig
->CleanupStoredContext();
pModuleConfig = NULL;
//
// It is possible that some other thread stored context before this thread
// could do. Check returned hr and return context stored by other thread
//
if
( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_ASSIGNED ) )
{
*ppModuleConfig = (MODULE_CONFIG *)pMetadataContainer->GetModuleContext( g_pModuleContext );
return
S_OK;
}
}
*ppModuleConfig = pModuleConfig;
return
hr;
}
HRESULT
MODULE_CONFIG::Initialize(
IHttpContext * pContext
)
{
HRESULT hr = S_OK;
IAppHostAdminManager * pAdminManager = NULL;
IAppHostElement * pAppHostElement = NULL;
BSTR bstrSectionName = NULL;
BSTR bstrConfigPath = NULL;
...
pAdminManager = g_pGlobalInfo->GetAdminManager();
...
//
// Read configuration data at metapath of IMetadataInfo object
//
bstrConfigPath = SysAllocString( pContext->GetMetadata()->GetMetaPath() );
...
hr = pAdminManager->GetAdminSection( bstrSectionName,
bstrConfigPath,
&pAppHostElement);
...
}
Hope this helps.
Kanwal
0 Comments
Blog - Comment List MSDN TechNet
Comments
Loading...
Leave a Comment
Name
Comment
Please add 1 and 6 and type the answer here:
Post