0

We have a huge set of apps that use a library called Auth.dll. This library is allways is installed in the GAC of our servers.

Now we are refactoring it, so we have split Auth.dll in two new ones

  • OAuth.dll
  • LegacyAuth.dll

When we deploy the refactored libraries (without recompiling the client apps) we get that they are not able to find the classes, because they have moved from Auth.dll to OAuth.dll. We made a mistake in assuming that respecting namespaces and class design would work

What do we need to do in order to accomplish refactoring Auth.dll, and library code file structure, without needing to recompile client apps?

Is there a better way to accomplish this than to do the following?


We are able to get these three libraries.

  1. OAuth.dll
  2. LegacyAuth.dll
  3. Auth.dll

We use inheritance in Auth.dll to reflect the refactored functionality that now is resides in the other libraries.

Note: Most of the classes that I am moving are structured like this:

public class UserEntity     
{   
   static public UserEntity FindByNif( string nif )
   {
        UserEntity ent = ....//operations;
        return ent;
   }
}

They return instances of the class itself

Krupip
  • 4,404
  • 2
  • 32
  • 54
X.Otano
  • 2,079
  • 1
  • 22
  • 40
  • A type is not just defined by its namespace and identifier name, it also includes the assembly it comes from. Try typeof(string).AssemblyQualifiedName to see this for yourself. So the failure mode is simple, the uncompiled assemblies use the wrong type name. They have to be recompiled. – Hans Passant Nov 08 '17 at 18:15

2 Answers2

0

You can not. It's not possible to do this without recompiling the client apps.

You might in the future build your client apps so dynamic that this would be possible, but not only would you need to recompile them to do that as well, but the effort doing this is much larger than just recompiling when you change your Auth libraries.

I suggest you write Unit tests before refactoring, so you will see when you introduce breaking changes in your code.


Assuming you'd do it all over from scratch, you could implement a factory pattern in your original library, so you only need to adjust the original library to return a different instance for your required interface and your client apps would only know the interface and have no need to be recompiled. However, that's what you should have done with hindsight. I'm afraid it's of no practical help for your current situation.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • ok, once is not possible which approach will be best? some workaround?? – X.Otano Nov 07 '17 at 11:37
  • There is no workaround. You need to recompile if you introduce breaking changes like that. Your best option is to make *all* changes and then recompile *once* and in the meantime write unit tests to find out which changes are breaking. – nvoigt Nov 07 '17 at 11:38
0

Here is an idea I did not try by myself, but in theory it could work:

  • provide a new version of Auth.dll, still containing all required classes, but implement them as adapters to the new classes OAuth.dll or LegacyAuth.dll. The adapters must be "interface compatible" to the former class versions (the public methods with their signatures must stay the same).

  • use assembly binding redirection (like described in this older SO post) to make the dependent applications load the new DLLs.

The second step requires to provide to deploy a new app.config for each of the apps, but no recompiling. However, you should ask yourself why you consider recompiling and redeploying such a big problem - these are steps which can (and should) be possible in a mostly automated way, otherwise you won't be able to quickly deploy any severe bugfixes which require a full redeployment.

To your edit: such an adapter could look like this:

namespace Auth
{
    public class UserEntity     
    {   
       OAuth.UserEntity oaUserEntity;
       public UserEntity(OAuth.UserEntity oaUserEntity)
       {
           this.oaUserEntity=oaUserEntity;
       }
       static public UserEntity FindByNif( string nif )
       {
            // delegate the logic to the new class implementation
            OAuth.UserEntity ent = OAuth.UserEntity.FindByNif(nif);
            return new UserEntity(ent);
       }
       // another example:
       public int SomeMethod()
       {
            return this.oaUserEntity.SomeMethod();
       }
    }
 }
Doc Brown
  • 19,739
  • 7
  • 52
  • 88
  • Hi, thanks Doc, you are allways helping a lot. Auth.dll contain classes that are not implementing interfaces or abstract classes. How can I do the adapation since most of methods are returning instance of itself?? (see edited question) – X.Otano Nov 07 '17 at 12:03
  • @Badulake: where in my answer did I write *Auth.dll* needs to provide interfaces? – Doc Brown Nov 07 '17 at 12:05
  • Yes, but I don´t know how to adapt Auth.dll classes as adapter, since the methods are returning instances of the classes – X.Otano Nov 07 '17 at 12:06
  • @Badulake: writing an adapter will need additional boilerplate code for every public function, but *only* boilerplate code. The core logic will be only in the new assemblies. – Doc Brown Nov 07 '17 at 12:16