Question

I have a WCF service, let's say assembly A, that is hosted in IIS. The WCF service has a reference to another assembly, let's say assembly B, which needs access to the Assembly object of assembly A.

Reason: I want to extend existing WCF services with an extra contract and default implementation of that contract, that can return the FILE VERSION of the WCF service assembly.

See my code below:

Assembly A (WCF Service):

web.config : Added a new endpoint in addition to the existing 2 endpoints under address "B"

<configuration>
  <system.serviceModel>
    <services>
      <service name="ExistingServiceHandler">
        <endpoint address="mex" kind="mexEndpoint"/>
        <endpoint address="" binding="basicHttpBinding" contract="IExistingContract"/>
        <endpoint address="B" binding="basicHttpBinding" contract="AssemblyB.IServiceContract"/>
      </service>
      ...

Existing implementation: Now extends 'Implementation' from assembly B.

public class ExistingServiceHandler : Implementation, IExistingContract
{
    // Whatever methods are implemented here
}

Assembly B (C# Class Library):

[ServiceContract]
public interface IServiceContract
{
    [OperationContract]
    string ServiceVersion();
}

public class Implementation : IServiceContract 
{
    public string ServiceVersion()
    {
        string assemblyLocation = Assembly.GetEntryAssembly().Location;
        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assemblyLocation);
        string fileVersion = fvi.FileVersion;

        return fileVersion;
    }   
}

I have tried the following (in assembly B), but none of them return the correct Assembly:

Assembly.GetEntryAssembly(); // returns NULL
Assembly.GetExecutingAssembly(); // returns assembly B
Assembly.GetCallingAssembly(); // returns System.ServiceModel

So, how do I get the Assembly for assembly 'A' (WCF Service)?

Note:

  • I want to use the contract + implementation from assembly B with minimal effort. That means I do not want to have to alter the existing service implementation, except for letting the class extend from my default implementation of the new contract (Implementation in assembly B). Thanks in advance!
Was it helpful?

Solution

It seems Assembly A never really calls into Assembly B, but simply extends its class. For that reason, GetCallingAssembly returns System.ServiceModel (WCF). I think you need to inspect this's type as follows:

[ServiceContract]
public interface IServiceContract
{
    [OperationContract]
    string ServiceVersion();
}

public class Implementation : IServiceContract 
{
    public string ServiceVersion()
    {
        string assemblyLocation = this.GetType().Assembly.Location;
        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assemblyLocation);
        string fileVersion = fvi.FileVersion;

        return fileVersion;
    }   
}

OTHER TIPS

The normal way you should not be forced to use Reflection and Assembly.GetSomething methods. Can't you inject some objects from Assembly A into Assembly B methods with some shared assembly of interfaces (contracts)? Here is a very very rough solution:

Assembly A

class Service
{
    public void ServiceMethod1()
    {
        // Here you create type from Assembly B but inject object from Assembly A
        var obj = new SomeClass(new SomeSharedClass()); 

    }
}

class SomeSharedClass : ISomeSharedContract
{
    // SomeMethod implementation
}

Assembly B

class SomeClass
{
    private ISomeSharedContract dependency;
    public SomeClass(ISomeSharedContract dependency)
    {
        this.dependency = dependency;
    }

    private HereYourMethod(...)
    {
        // ...
        this.dependency.SomeMethod(); // Here you gain access to Assembly A object
        // ...
    }
}

Assembly C - Interfaces

interface ISomeSharedContract
{
    void SomeMethod();
}

You can extend this sample by usage of some common Dependency Injection container like Unity, ninject or Windsor Castle...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top