1

I am new to creating custom service applications, and I have been following the walkthrough given here to begin building my own.

In that example though, the service app is built to only allow one instance of itself in the farm, and I want to make one that can have multiple instances (much in the same way that you can create multiple Managed Metadata service applications, or multiple Search Service applications).

The problem I'm running into is when it comes to the client invoking the service, I need to be able to connect to the correct proxy for an individual service app instance.

In the walkthrough example, the client calls a static Invoke method on the application proxy class:

///////////////
/////////////// client code:

public int Add(int x, int y)
{
    int result = 0;

    // run the call against the application proxy
    CalcServiceApplicationProxy.Invoke(_serviceContext,
        proxy => result = proxy.Add(x, y));

    return result;
}

///////////////
/////////////// application proxy code:

internal static void Invoke(SPServiceContext serviceContext, CodeToRunOnApplicationProxy codeBlock)
{
    if (serviceContext==null)
        throw new ArgumentNullException("serviceContext");

    // get service app proxy from the context
    CalcServiceApplicationProxy proxy = (CalcServiceApplicationProxy)serviceContext.GetDefaultProxy(typeof(CalcServiceApplicationProxy));
    if (proxy == null)
        throw new InvalidOperationException("Unable to obtain object reference to calc service proxy.");

    // run the code block on the proxy
    using (new SPServiceContextScope(serviceContext))
    {
        codeBlock(proxy);
    }
}

In the proxy Invoke method, it's getting the default proxy of that proxy type. This is all well and good for the walkthrough example, because we know there is only going to be one Calc Service Application, and therefore only one Calc Service Application Proxy. But this is exactly where I need to be able to differentiate between individual proxies (and therefore individual service applications).

Now, I've figured out that if I know an individual proxy's ID, I can modify the Invoke method to get a specific proxy:

internal static void Invoke(SPServiceContext serviceContext, Guid proxyID, CodeToRunOnApplicationProxy codeBlock)
{
    // code omitted for brevity

    MyCustomSvcAppProxy proxy = (MyCustomSvcAppProxy)serviceContext.GetProxies(typeof(MyCustomSvcAppProxy)).Where(prx => prx.Id.Equals(proxyID));

    // code omitted for brevity
}

And, given an individual proxy's ID, I can store that somewhere accessible (maybe in a property bag) so that when a client needs to call the service, it can grab the proxy ID and connect to the correct proxy.

But when setting up and configuring the service app, I can't see how to find the ID of the proxy that belongs to that service app instance. I can see that the SPIisWebServiceApplication class has a ServiceApplicationProxyGroup property, but that appears to be a group of all proxies for all the different types of service apps? And in any case, from the ServiceApplicationProxyGroup property documentation: "A proxy group can contain multiple service applications of the same type." So even if I were to pull out all of the application proxies of my custom type, if I had more than one instance of a service application running, there would be more than one proxy... And the SPServiceApplicationProxy class does not appear to have any property along the lines of "ServiceApplication" or anything to indicate how it knows which service app to connect back to.

So... how do I find out which particular proxy corresponds to an individual service application instance?

EDIT 12/9

I managed a kind of workaround for this -- since I am storing the individual settings of a service application instance as an SPPersistedObject child of the service app instance, and since I have a reference to the service app instance and the proxy at the time that I create the proxy, I can store the proxy's ID as one of the service app's settings. That way, the service app instance sort of "knows" it's own proxy's ID, and I can get to it when I need to.

I'd still like to know if there's a better way to tell which proxy belongs to which service app instance, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.