views:

157

answers:

4

I would like to have a variable defined in my web.config that I can use in multiple places within my web.config file (and other config files). It's probably easier to explain by example ...

web.config

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
    </appSettings>
    <system.web>

    ...

    <system.serviceModel>
        <client>
            <endpoint
                address="net.tcp://localhost/AuthService"
                binding="netTcpBinding"
                contract="MyServices.Contracts.IAuthService"
                name="#{AppSettings.AuthServiceEndPoint}"
                bindingConfiguration="netTcpBindingConfig"
            />

        </client>
    </system.serviceModel>
</configuration>

windsor.config

<?xml version="1.0" encoding="utf-8" ?>
<castle>
    <components>

        ...

        <component
            id="AuthProvider"
            service="MyServices.Client.IAuthProvider, MyServices.Client"
            type="MyServices.Client.AuthProvider, MyServices.Client"
            lifestyle="transient">
            <parameters>
                <endpoint>#{AppSettings.AuthServiceEndPoint}</endpoint>
            </parameters>
        </component>

    </components>
</castle>

Is this possible?


Edit (a bit more information)

I already have the ability to access the AppSettings from my windsor.config file (which is actually processed by castle windsor and a custom XmlInterpreter.

The real question is can I do this in my web.config?

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
    </appSettings>
    <system.web>

    ...

    <system.serviceModel>
        <client>
            <endpoint
                address="net.tcp://localhost/AuthService"
                binding="netTcpBinding"
                contract="MyServices.Contracts.IAuthService"
                name="#{AppSettings.AuthServiceEndPoint}"
                bindingConfiguration="netTcpBindingConfig"
            />

        </client>
    </system.serviceModel>
</configuration>

ie - access variable in my <appSettings> from other parts of my web.config file.

A: 

Not that I can think of. You could do your configuration in C# in global.asax.cs instead of the xml file.

Alternatively, have your web.config edited by your build process to replace all these values. FinalBuilder has a neato "Edit XML File" action that uses XPath quite well to do this, and FinalBuilder does have variables. Problem solved. This is how I do my builds at work.

Neil Barnwell
A: 

Off the top of my head, I wonder if you might be able to do this with T4? I'm thinking that perhaps you could define a template which parses Web-Template.config and outputs Web.config? Of course, this only works for a single file.

Damian Powell
A: 

You can use NAnt or MSBuild for this. You do need separate configuration files for both, but when you build your project they can automatically do transformations on your Web.config and other configuration files.

Tchami
A: 

Here I go answering my own question again :-S

I solved this by writing a NetTcpServiceLocator ...

public interface INetTcpServiceLocator
{
    EndpointAddress GetAddress(Type serviceType);
}

... along with a custom config section handler which also implements the above interface and reads in the following config section ...

<services>
    <service contract="My.Services.TestService.Contracts.ITestService" address="net.tcp://localhost/TestService" />
</services>

Then I created a proxy for each service ...

public class TestServiceProxy : ITestService
{
    public SomeInformation GetSomeInformation(SomeParams @params)
    {
        using (var factory = new NetTcpServiceFactory<ITestService>())
        {
            var service = factory.Service;
            return service.GetSomeInformation(@params);
        }
    }
}

My Controller has a dependency on a Service, which has a dependancy on ITestService. All this is glued together with Castle Windsor and by using property dependency injection.

So, my controller calls it's Service, which in turn calls the ITestService (in this case a proxy, which gets it's endpoint from the custom section handler).

The custom section handler (which is also the INetTcpServiceLocator) has a windsor lifestyle of "perWebRequest", so it gets called by the framework and web.config is read into an array in memory. When the service proxy is called, it then just pulls the relevant endpoint based on the contract type.

It's all driven by the type of the contract, so there is no need to have any variables in web.config anymore.

I've gone for a code based solution, as I don't use a build process locally, only when I submit my code to subversion does the build process kick in on our build server.

Antony Scott