0

I've been trying to write a simple little Cmdlet to allow me to Set/Get/Remove cache items. The problem I have is that I cannot figure out how to connect to the local cache cluster.

I've tried adding in the usual app.config stuff, but that doesn't seem to get picked up ...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="dataCacheClient" type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere" />
  </configSections>
  <dataCacheClient>
    <hosts>
      <host name="localhost" cachePort="22233" />
    </hosts>
  </dataCacheClient>
</configuration>

I'd rather not have that config at all. So what I am really asking is what the equivalent C# code is for the following powershell...

Use-CacheCluster

From what I can gather Use-CacheCluster connect to the local cluster if no parameters are supplied

Antony Scott
  • 21,690
  • 12
  • 62
  • 94

2 Answers2

1

I've just done some spelunking into the AppFabric Powershell code with Reflector to see how it works under the covers. If you call Use-CacheCluster with no parameters e.g. for the local cluster, the code reads the connection string and provider name from the Registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AppFabric\V1.0\Configuration. Unfortunately, it then uses those values to build a series of classes (ClusterConfigElement, CacheAdmin and ClusterHandler) which are all marked as internal, so you can't use them to pick up the current cluster context (for want of a better word) that Powershell is working with.

To make your Cmdlet work, then, I think you need to pass in a hostname (which would be one of the servers in your cluster, and perhaps you could default this to the local machine name) and a port number (which you could default to 22233), and use those values to build a DataCacheServerEndpoint to pass to your DataCacheFactory e.g.

[Cmdlet(VerbsCommon.Set,"Value")]
public class SetValueCommand : Cmdlet
{
    [Parameter]
    public string Hostname { get; set; }
    [Parameter]
    public int PortNumber { get; set; }
    [Parameter(Mandatory = true)]
    public string CacheName { get; set; }

    protected override void ProcessRecord()
    {
        base.ProcessRecord();

        // Read the incoming parameters and default to the local machine and port 22233
        string host = string.IsNullOrWhiteSpace(Hostname) ? Environment.MachineName : Hostname;
        int port = PortNumber == 0 ? 22233 : PortNumber;

        // Create an endpoint based on the parameters
        DataCacheServerEndpoint endpoint = new DataCacheServerEndpoint(host, port);

        // Create a config using the endpoint
        DataCacheFactoryConfiguration config = new DataCacheFactoryConfiguration();
        config.Servers = new List<DataCacheServerEndpoint> { endpoint };

        // Create a factory using the config
        DataCacheFactory factory = new DataCacheFactory(config);

        // Get a reference to the cache so we can now start doing useful work...
        DataCache cache = factory.GetCache(CacheName);
        ...
    }
}
PhilPursglove
  • 12,511
  • 5
  • 46
  • 68
  • I found the same code in reflector. I was hoping to avoid having to pass config in. The problem I have is that I want this to just "work" in whatever cluster I happen to be running it on. I have a local cache for development, but my production cache runs across 3 VMs. I guess this is the best we can hope for until Microsoft release a ".Server" nuget package for us to use. – Antony Scott Jul 26 '12 at 12:32
  • @AntonyScott FWIW I think it's a bad design decision by MS, means we need to replicate all that work in our own Cmdlets instead of working in a PowerShell-y way – PhilPursglove Jul 26 '12 at 12:53
  • agreed. a .NET assembly would have been nicer then we could have just used that to write cmdlets. Trying to use a cmdlet to reverse engineer it is not good :S – Antony Scott Jul 26 '12 at 12:57
  • I've actually rewritten my app as a powershell module, but am marking this answer as accepted as it answers the question I actually asked which was really about cmdlets – Antony Scott Aug 01 '12 at 09:49
0

The problem is that the call: DataCacheFactoryConfiguration config = new DataCacheFactoryConfiguration();

inside Cmdlet mothods produces an error sounding like "Cannot initialize DataCacheFactoryConfiguration".