How to notify developers of external framework constraints? - c#

We have code that is called by an external framework, ARDEN. Short of a comment (easily overlooked), how can I effectively notify developers of tie in's to this framework? Specifically, a tie in couples the CLASS, NAMESPACE and METHOD to said framework.
namespace MyCompany//changing namespace for this class is NOT SAFE
{
public class MyClass//changing class name is NOT SAFE
{
[TiedToArdenAttribute]//maybe an attribute?
public void MethodCalledByArden() {}//adding params, changing name is NOT SAFE
public void NotCalledByArden() {}//changing this method signature, name, params is OK
}
}
Under normal circumstances, for example when I change the name of MyClass in an assembly via visual studio I can't compile without fixing the references to said class. If the namespace, classname or method name changes...there should be a warning that says "best fix Arden to deal with this change". I considered an Error, but since there's no way to verify Arden is fixed I don't believe that will work.
Is there a way to achieve a similar result for this external framework?

I think whatever you do can be undone by other developers - they can rename class, remove comments, remove attributes.
Try to move this class to separate library instead. And in your project add reference to compiled assembly. That will make class name fixed in your project.

If others are using the code, it is best to talk in terms of contracts and not class instances via interfaces. By allowing the consumer to use an Interface will dictate the primary changes such as property changes...but things like internal class name changes will not affect a consumer. Plus you can version your classes, while working on a new class, the old class could still be used by the consumer until the factory internally releases it, without the consumer knowing that V2 of the class is being used.

Related

Object name inside of referenced .dll changed blowing up application

I would appreciate it if someone would explain to me how .NET references work when a .dll is compiled.
I have two .dll-s, my primary application.dll references my services.dll. The purpose of the services.dll is to provide a decoupled layer for communication with third party services so that changes to the integrations do not affect the application directly.
To achieve this decoupling I have inherited the services primary object exposing and using the new object in the main application:
public class CustomClient : ServiceClient_v1
{
public CustomClient(binding, address) : base (binding, address) {}
}
However, I am finding that when ServiceClient_v1 gets updated to ServiceClient_v2 and I try and just update the services.dll then my application.dll blows up saying:
Could not load type "ServiceClient_v1" from assembly services.dll
So it is still hanging onto a direct reference to that other object that I am trying to hide. I assume this is by design and simply something to do with compilation that I do not understand.
Is there a way to achieve what I want? And why is my method not working?
Since you're deriving CustomClient from ServiceClient_v1 in your application.dll, it will only work with the older version of your services.dll that contains the definition of ServiceClient_v1. As Lasse Vågsæther Karlsen pointed out, the ServiceClient_v1 class becomes part of the public declaration of CustomClient.
I believe you would benefit from applying Dependency Injection and the Liskov substitution principle in your application.
In order to achieve your goal of a truly interchangeable services.dll you need to refactor your architecture removing the dependency of services.dll from application.dll, it should be the other way around.
Define an Interface for your ServiceClient type. Both CustomClient and ServiceClient_v1 must implement this interface.
When you later update the code to use ServiceClient_v2, it should also implement the interface, which will be unchanged. Now everything continues to work without needing to re-complile the application.dll project.
Alternatively, don't rename the ServiceClient type in services.dll when moving from v1 to v2. This is what version control systems like git or SVN or are for.

Saving a C# class definition

Is there any way to save an entire class definition for a C# object to a file / data store?
I use the [Serializable] tag and ISerializable interface to do this already, but both of these rely on the object definition being in the assembly at run time.
What I'm looking for is a solution to the following scenario:
1) User creates object MyClass in my software and saves it
For the purpose of this example, MyClass is a stand-alone object that doesn't rely on any other class in the system:
i.e. this could be the entire definition:
public class MyClass
{
public int MyProperty { get; set; }
public void DoSomething() { /* do something, like Console.Write(""); */ }
}
2) We release a patch that removes MyClass from the system
3) User loads the saved MyClass from step 1 and calls DoSomething() on it - and has the function work exactly the same as it did before the patch removed the class from the system
Is there any way this can be done without reflection / emit trickery?
No, this won't work without emitting the type definition. What you are trying to do is actually save off the code (otherwise, how would DoSomething work?) - which is what the compiler does for you. Plain serialization will never work for you here.
So, if you need to save behavior as well as state, you need to either keep the historical code around, use some type of reflection emit trickery to persist the type definition as a loadable assembly, or use dynamic programming tricks that treat data as executable code.
When I have had do versioned serialization before, I normally have custom serialization logic and a "version" attribute on the object - using this I can create a type that I've moved and renamed - say SomeClass to Archive.SomeClassV3. You can use Version Tolerant Serialization for this, but I prefer to implement ISerializable and use serialization proxies if this is required. (Well, actually I prefer to avoid this problem altogether!)
Well, you could keep all of these serializable classes in their own DLLs, package the DLLs with the application, and have the DLLs loaded at runtime. That way, even if you remove the classes from the latest version of the application, the loaded DLLs will still work.
This seems like a scary approach, though ... now you have clients running ancient code that you no longer even have in your source control repository. How are you supposed to debug that?
You talking about not class-property serialization, but about process-serialization (or method-, doesn't matter). But unlike property serialization, this should contain MSIL-code that runs when you need it. So you must somehow translate it to a bin-code and then run by Assembly.Load, for example. I guess this is not an easy way to do this. So, if this is possible - store your implementation of MyClass to a separate dll, or as a string (in c# language) for further compilation and execution by reflection.

Circular References in my C# projects

I have the following situation:
A project MyCompany.MyProject.Domain which contains my domain model, and partial classes (such as Contact).
I want to 'extend' (by partial class, not extension method) my Contact class with a property Slug which will give me a simple URL friendly text representation of first and last name.
I have a string extension method ToSlug() in my Utility project MyCompany.MyProject.Utilities which does exactly what I want in 2).
The problem: My Utility project is already referencing my Domain project which means that I can't get the Domain project to see the Utility project's ToSlug() method without causing circular reference.
I'm not keen on creating another project to solve this, and I really want to keep the Slug logic shared.
How can I solve this?
Your Utility project referencing your MyCompany.MyProject.Domain seems like a bit of a code smell. I'm assuming here that these are utilities that specifically work on domain objects--if that's the case, then why don't you include MyCompany.MyProject.Utilities within your Domain project (naturally, modifying the namespace accordingly)?
In any case, the normal way to break these kinds of dependencies is to abstract what is required by one project into a set of interfaces, and encapsulate those in a separate assembly. Before doing that though, make sure that what you're doing conceptually is the right thing.
In your particular situation though, consider introducing an interface, viz., INameHolder:
public interface INameHolder
{
string FirstName { get; set; }
string LastName { get; set; }
}
Then Contact implements INameHolder. INameHolder exists in another assembly, let's call it MyCompany.MyProject.Domain.Interfaces.
Then your Utilities project references Interfaces (not Domain) and so does Domain, but Interfaces doesn't reference anything--the circular reference is broken.
copy ToSlug method to Domain project and Delegate Utility's ToSlug call to this new method
If you cannot share the domain (probably right) and it must consume the logic from a shared library then then you really have to introduce a another assembly.
Or you could load the logic at runtime in the domain by reflection in the domain to access the dependent library. Its not hard just breaks compile time checking.
If you're sure about keeping the code in the utility DLL (Eric's answer seems smart to me), then you could create an interface in your utility project, pass that interface as a parameter to your ToSlug method and then have your domain object implement the interface.

ASP.NET + C# Multi-Project Solution. Where should I put my global utility functions?

As the Title says, I've got a multi-project solution.
I've got a "core" project that is loaded with most of the other projects.
So my question is this, I have a few utility functions such as FormatPhoneNumber(..) that I would like to be able to access in the following manner from anywhere.
(in Project_B which depends on Core)
string str = FormatPhoneNumber(inputString);
At worst, I suppose I could live with a qualifier of some sort:
string str = util.FormatPhoneNumber(inputString);
The best way of doing this is to create a dll project (maybe called something like "CommonCode"?), that you can then reference this dll from all of your other projects and access the classes and methods therein.
You will have to have some sort of "qualifier" (as you call it) somewhere, but to reduce the impact use the using statement at the top of each file, e.g.
using util;
If you really must have such utility functions (you know, you shouldn't, but sometimes it's the best/easiest solution), I suggest having them either in the Core (assuming that every single project is dependent on the Core anyway), or in a separate utility assembly. If you don't want to have a separate assembly lying around, consider using ILMerge.
The qualifier should be no problem at all. I suggest not putting unrelated function into an Utils class, but rather use e.g. a Formatting class for all formatting functions. On the other hand, as s_ruchit in the meantime suggested, extension methods (e.g. for the string class) might come in handy as well.
(Did I mention that this §%$& MarkDown editor does not allow typing an [at] symbol on a German keyboard layout, because it instead creates a blockquote? Sigh.)
Try creating your own util library.
Create a Class Library project and put your util classes in there.
I myself try to adhere a naming convention like [companyName].Util.[subdomain]
Your example would probably fit in my [CompanyName].Utils.StringHelpers
You would then create a static class StringHelper with a static method FormatPhoneNumber.
You will see that these personal libraries quickly grow bigger. By grouping them you don't have to load all your code if you only need a subset of functions.
Use an extension method to make it easier to call the method without using the class name.
public static class Util {
public static string FormatPhoneNumber(this string input) {
:
}
}
The method will now appear on every string object. You do not need to know which class it comes from. However, if the extension class is declared in another namespace, you must still import the namespace.
string formattedString = inputString.FormatPhoneNumber();
If you are using C# 3.0, you can bind them all into one single static class use them as Extension Methods.
There are no global functions in .NET, so you will have to put your utility functions into a class. You can make the methods static, so you can call them without having to instantiate the utility class:
public class Utility
{
public static string FormatPhoneNumber(string input)
{
...
}
}
// usage:
string output = Utility.FormatPhoneNumber(input);
Put these methods into your core library or a separate utility library that can be used (referenced) by all other libraries and applications.
You need to put the functions in static classes. You cannot avoid the qualification (there are no global functions in C#):
<%= Formatters.PhoneNumber(rawData) %>
The utility functions should be grouped as per normal methods: similar methods go together, unrelated methods should go into different classes (event with static classes aim for low coupling and high cohesion).
The assembly each belongs in should be obvious: formatting functions only used by the presentation layer (ASP.NET project itself) belong there. Truly common functions could go into core.
If the function you are implementing can only be used in context of your application, i would recommend you to place it into the Core assembly (under a separate namespace like "Utils" for example) or a new DLL library of your application solution.
Only if the function can be used across multiple projects it makes sense to create a utility library. But always keep in mind that a utility library only make sense if it's maintained regularly.
If you want all code to access these methods then go with extension methods, otherwise I would go with Util class in core assembly.
FWIW, if you follow a more formalised namespace as boris sugguests (recommended to avoid conflicts) you can abbreviate with the using keyword:
using Util = [CompanyName].Utils.StringHelpers;
I tend to follow the DRY principle and create an alias as soon as I need it more than once.

Is there a way to derive from a class with an internal constructor?

I'm working with a 3rd party c# class that has lots of great methods and properties - but as time has gone by I need to extend that class with methods and properties of my own. If it was my code I would just use that class as my base class and add my own properties and method on top - but this class has an internal constructor. (In my opinion it was short sited to make the constructor internal in the first place - why limit the ability to subclass?)
The only thing I could think of was to create method / properties on my class that simply called into theirs - but it's acres of code and, well, it just doesn't "feel" right.
Is there any way to use this class a base class?
You ask: "Why limit the ability to subclass?"
Because designing for inheritance is tricky, particularly if you're designing for other developers to inherit from your class. As Josh Bloch says in Effective Java, you should design for inheritance or prohibit it. In my view, unless you have a good reason to design for inheritance, you shouldn't do so speculatively.
Does the class implement an interface which you could also implement (possibly by proxying most calls back to an instance of the original)? There's often no really elegant answer here - and the best solution will depend on the exact situation, including what you're trying to add to the class.
If you're not adding any more state - just convenience methods, effectively - then extension methods may work well for you. But they don't change what data an object is capable of storing, so if you need to add your own specialised data, that won't work.
Sounds like a perfect application for extension methods:
MSDN extension method docs
"Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type."
If the class has an internal constructor, and there are no public constructors, then that suggests that the designers did not intend for it to be subclassed. In that case, you can use encapsulation, or you can use extension methods.
Only if your class lives in the same assembly as the class you want to inherit from. An internal constructor limits the concrete implementations of the abstract class to the assembly defining the class. A class containing an internal constructor cannot be instantiated outside of the assembly.
Resharper has a nice feature to create delegating members.
Here is a sample of what you can do with it. It takes a couple of seconds.
I will not discuss whether you can build your own Facade around that 3rd party class. Previous authors are right, the library could be designed in the way that will not allow this. Suppose they have some coupled classes that have singletons that should be initialized in specific order or something like this - there may be a lot of design mistakes (or features) that 3rd party developers never care about, because they do not suppose that you will use their library in that way.
But OK, lets suppose that building a facade is not an impossible task, and you have in fact only one problem - there are too many methods you have to write wrappers around, and it is not good to do this manually.
I see 3 solutions to address exactly that problem
1) I suppose that new "dynamic" types of .NET 4.0 will allow you to workaround that problem without having to write "acres of code"
You should incapsulate an instance of 3rd party class into your class as a privare member with dynamic keyword
Your class should be derived from Dynamic or implement IDynamicObject interface. You will have to implement GetMember/SetMember functions that will forward all calls to the encapsulated instance of 3rd party class
Well, c# 4.0 is a future, Let's see on other solutions:
2) Do not write code manually if you have significant number of public methods (say more then 100). I would write a little console app that uses reflection and finds all public members and then automatically generates code to call encapsulated instance. For example
public type MethodName(params)
{
this.anInstanceOf3rdPartyClass.MethodName(params);
}
3) You can do the same as 2, but with the help of existing reflection tools, for example RedGate .NET Reflector. It will help you to list all classes and methods signatures. Then, paste all this in Word and a simple VB macro will let you generate the same code as you could do in 2.
Remark: As soon as you are not copying the code, but only copying method signatures, that are publicly available, I don't think you will violate the license agreement, but anyway it worth to re-check

Categories