Click here to Skip to main content
15,885,914 members
Articles / Programming Languages / C#

Non-Intrusive Frameworks

Rate me:
Please Sign up or sign in to vote.
4.68/5 (10 votes)
5 Feb 2020CPOL5 min read 7.9K   2   1
What is a non-intrusive framework and whether it is really possible for a framework to be non-intrusive

Introduction

Many times, I have talked about non-intrusive frameworks as part of a different talk. Lately, I had to deal with this kind of architecture again and I tried to find a concise explanation on non-intrusive frameworks but, instead of finding good explanations, I found questions with answers like "How can a framework be non-intrusive... you want to use it, without referencing it?" and that's really off and not helpful.

So...

What Makes a Framework Intrusive or Non-Intrusive?

To answer this question, I think the best we can do is to consider what a framework is supposed to do and then focus on how they can be intrusive or not.

Considering virtually "anything" can become a framework, I will focus on a particular kind of framework: A framework that is supposed to give "extra powers" to existing types. For other frameworks, being intrusive or not might not apply at all.

What I Mean by Extra Powers?

Let's see:

  • There are frameworks that allow us to "save" our own types as XML (or JSON or any other format). Those are known as serialization frameworks.
  • There are frameworks that allow us to expose a "local" class to a remote computer. Those are communication and/or remoting frameworks.
  • There are frameworks that are responsible for giving us "objects" of a given type, even if we don't know how to provide all the arguments those objects require to be constructed (those are usually called IoC containers - Inversion of Control containers).
  • There are frameworks that allow us to visualize existing types by attaching "data-templates" or similar (WPF, for example).
  • And frameworks can be as simple as: I want to convert any given object to string (or some other type).

Now that we know what a framework can do, let's explore how the frameworks can be intrusive, as this will help us understand the entire problem.

We have a class:

C#
public class MinimumPersonInfo
{
  public int Id { get; set; }
  public string Name { get; set; }
}

And just to make things "simple", we have:

C#
class TheSerializer
{
  byte[] Serialize(object itemToSerialize); // This is just the signature.
}

Assuming we want to serialize a MinimumPersonInfo, we do:

C#
var objectToSerialize = new MinimumPersonInfo { Id = 123, Name = "Test" };
var serializedBytes = someSerializer.Serialize(objectToSerialize);

Does It Work?

If it does, I will say the framework is non-intrusive.

If it fails, there's a chance it is intrusive.

So, why did it fail?

  • Your class doesn't have the [Serializable] attribute.
  • Your class doesn't have the [XmlSerializable] attribute.
  • Your class isn't a sub-class of TheSerializerSerializableBase.
  • Your class uses a property of type string, when it should use SerializableString.
  • Your class has public properties, when it is supposed to have public fields.
  • For some odd reason, you had an OutOfMemoryException.

So... except for the last case that seems to be an odd case (and assuming it was really a case where the computer ran out-of-memory and not just a bad exception type), the other cases mean the framework is intrusive.

It is not just the code that wants to use the framework that needs to reference it. Even the code that was not even supposed to know there was a framework involved is required to change, using attributes, base classes or just replacing properties by public fields (which is considered a programming-design violation).

Let's Try Again: How Can a Framework Be Intrusive?

By asking the target types that they try to give some extra functionality to, to change, to adequate themselves to the framework needs, when the framework was supposed to give them the extra-powers "for free".

How Can a Framework Be Non-Intrusive?

By requiring that only the users of the framework know about their existence, and nobody else.

Any type that ends-up given to the framework is not required to know about its existence or "change" to follow some framework-specific guidelines or protocol.

In particular, that means that your app can use the framework with third-party libraries that do not know about the framework you are using.

Basic Example?

Can you serialize a UnityEngine.Vector3?

That type is perfectly serializable, but it doesn't include the [Serializable] attribute, [XmlSerializable] or anything similar. Also, I don't try to change third-party assemblies, so, how do I use a framework that requires those attributes to just serialize that type, without creating adapters?

Better question, should I use a framework like that?

Are There Non-Intrusive Frameworks?

Sure. WPF data-templates do it. You attach data-templates to data-types that are completely unaware about their "visualization template". The same way, we can just use "dictionaries" to map a type to a binary serializer, XML serializer or the like. To map a conversion from any type to any other type, and those don't need to change the original libraries. It is like, if I want to convert a UnityEngine.Vector3 to "My3Doubles", it is feasible and maybe my app will need to setup the framework to do that properly, but as long as I don't need to change UnityEngine types, that means the framework that does the conversion is non-intrusive.

Can I Avoid a Reference to the Framework?

Yes and No. No if we are talking about the "user" of the framework, but when the framework gives extra-powers to existing types, sure. That's how non-intrusive frameworks should work! The types that are given the extra-powers don't need to change at all!

GRpc and Similar Technologies. Are They Intrusive?

I am asking this question knowing that many people say "no", because they think "you don't need to change your base code, you just need to create the right objects to be serialized". But, in practice, the answer is: They are the worst cases!

As the GRpc framework can't deal with anything that it is not its own types or just the most basic types, developers either:

  1. convert their own types to the GRpc types (run-time conversions with adapters) or;
  2. start to use the GRpc types everywhere.

And number two is the most common, and the worst. It is not only when they need to call the library, developers start to replace any well-known design and architecture patterns by their library (pattern) just to use it. I am not saying it doesn't work. The library works great. It is just that to use it, developers go to the extreme of bad design, creating libraries that are completely tied to how they communicate externally (even when they don't need to call external methods) and becoming just "bad code" that is hard to understand, reason about or to fix.

Sometimes, it is better to solve the problem at the source: Never use protobuffers, flatbuffers or similar as your "C#" data-type. Just use C# code and, if any conversion is needed, let the framework do it, never expecting the developers to do it at every call-site as that's definitely bad design!

History

  • 5th February, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Microsoft
United States United States
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.

At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.

Want more info or simply want to contact me?
Take a look at: http://paulozemek.azurewebsites.net/
Or e-mail me at: paulozemek@outlook.com

Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (in October 2014 I started working at Microsoft, so I can't be a Microsoft MVP anymore).

Comments and Discussions

 
QuestionSo, when does a framework become a pattern? Pin
George Swan11-Mar-20 22:05
mveGeorge Swan11-Mar-20 22:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.