Does this sound interesting to you and your company?
Then please contact us.
Whether it’s large frameworks or libraries, or small tools or collections of useful functions: it seems as though solutions already exist for every problem. Most of the time, these are available for free as open-source software (OSS). Sometimes they cost money, but these days the costs are often very low. An hour of a developer’s time is significantly more expensive. Third-party software can be quickly integrated thanks to package managers. This often pleases developers and project managers alike—after all, it saves us all time and money. So what’s the catch?
In most cases, nearly 100% of software development costs consist of personnel expenses. This creates a strong incentive to save developer time. The promise of a tool that reduces developer time is therefore an obvious one. And the conclusion that using off-the-shelf software to “buy in” parts of the development process is, in principle, correct—because only by reducing development effort can time, and thus money, be saved in the end.
But this is also where the problem lies. How exactly do you assess whether off-the-shelf software can save time? It’s not the initial implementation, but rather the time spent troubleshooting issues and continuously maintaining the software that drives costs. These time expenditures depend primarily on whether the development team understands the software and is thoroughly familiar with the code. With third-party software, this is only possible after a long training period and a great deal of experience. In any case, weighing the pros and cons of using third-party software versus writing your own is no simple matter, as the follow-up costs are very difficult to estimate.
There is often a tendency to overestimate the promises at the outset, since the decision is made based on incomplete data and the immediate positive effects outweigh the drawbacks (less time required in the short term for training and integrating third-party software). Package managers like NuGet or npm have taken this principle to the extreme and have drastically simplified the process of finding and integrating third-party software.
The decision to develop software in-house or use off-the-shelf software is usually based on limited experience. Furthermore, it may not become clear until later whether there are functional differences that aren’t apparent at first glance. These differences only surface later in the implementation process—a problem that cannot be completely eliminated.
So, to make a good decision, you need factors that allow you to determine—even with limited knowledge—whether “make” or “buy” is the better choice. The following tips can simplify the decision.
“It offers so much—we're definitely well-positioned for the future.”
The argument might go something like this if you only need a small part of the third-party software. But what if that’s all you need? Wouldn’t it be easier to write the functionality yourself? Do I really need a component like leftpad?
It makes sense to take a look at the scope of the solution you need. Sometimes there are no real arguments in favor of the more complex off-the-shelf solution, yet you still opt for it because of potential you’ll never fully utilize.
“External components are maintained and updated independently”
It is certainly true that third-party components often receive updates and security patches that enhance functionality and improve stability. The maturity a third-party component has achieved is a key indicator of its future viability. Factors include:
These factors seem straightforward to evaluate; for example, the star ratings on GitHub provide an indication of the software’s popularity. Market acceptance or the question of the business model, however, can often only be assessed qualitatively.
Regardless of the factors mentioned above, some effort is always required for integration. With in-house development, this effort is already factored in. With third-party software, integration often involves gaining an understanding of the system through documentation and trial and error. This effort tends to be greater for more complex solutions. For smaller solutions, it may therefore make sense to develop them in-house to ensure they are future-proof, since with in-house development, the company’s own development team knows the solution inside and out and can keep it stable.
Neither is free, because keeping things up to date always requires some effort to integrate, even though automated version control in package managers and approaches like semantic versioning are used in an attempt to escape “dependency hell” (e.g., caused by numerous dependencies and dependency cascades).
An example from one of our software teams—which develops software using WPF and .NET—shows just how simple implementation can be. For this project, they used the Caliburn.Micro framework. The primary reason was to utilize the MVVM pattern.
The decision was easy, because Caliburn.Micro is free and very easy to use and integrate. By limiting themselves to the MVVM pattern, the team had chosen only a small, isolated part that was important to them. Nevertheless, problems arose relatively early on that made development unnecessarily complicated:
So, the first step was to assess the scope of the solution. The MVVM pattern itself is a smaller, isolated component. It can be easily separated and implemented independently, without any dependency on Caliburn.Micro. The integration and familiarization with the external framework required a similar amount of effort.
The implementation of our in-house development therefore involved:
We can now implement our own ideas more easily and quickly, and the code is much clearer and leaner, since we’ve implemented only the functions we actually need. Our framework is thus much easier to understand and therefore ready for any maintenance or expansion. The use of our company’s proprietary standard formats and structures makes it easier to work with the software internally. This makes it easier to resolve issues using existing solutions.
The fact that it doesn’t require much programming effort is demonstrated by the code we wrote ourselves, which reflects the benefits we hoped to achieve with Caliburn.Micro.
///
/// Searches for View models and views that match the name convention and adds them to the resource dictionary
///
/// The namespace in which will be searched for the view models
/// Reference to Dictionary in which the template should be stored
/// Array of types that contains among other types, the view model types and view types
/// List that contains the imported templates
public static List GenerateTemplateDictionary(String typeNamespace, ResourceDictionary res, Type[] relTypes)
{
// get names of namespaces for VMs and Views by convention
String vmNs = $@"{typeNamespace}.ViewModels";
String viewNs = vmNs.Replace("Model", String.Empty);
// getting types of VMs and Views from that namespaces
var viewModelQuery = from t in relTypes
where t != null && t.IsClass && !t.IsAbstract && t.Namespace != null && t.Namespace.StartsWith(vmNs)
select t;
var viewModelTypeList = viewModelQuery.Where(t => t != null).GroupBy(t => t.Name).Select(g => g.First()).ToDictionary(t => t.Name, t => t);
var viewQuery = from t in relTypes
where t != null && t.IsClass && !t.IsAbstract && t.Namespace != null && t.Namespace.StartsWith(viewNs)
select t;
var viewTypeList = viewQuery.Where(t => t != null).GroupBy(t => t.Name).Select(g => g.First()).ToDictionary(t => t.Name, t => t);
var foundItems = new List();
// link the VM types to View types by convention into a datatemplate and add the datatemplate to app.resources
foreach (var vmt in viewModelTypeList)
{
var viewKey = vmt.Key.Replace("Model", String.Empty);
if (viewTypeList.ContainsKey(viewKey))
{
var viewType = viewTypeList[viewKey];
var template = CreateTemplate(vmt.Value, viewType);
if (!res.Contains(template.DataTemplateKey ?? throw new InvalidOperationException()))
{
res.Add(template.DataTemplateKey ?? throw new InvalidOperationException(), template);
foundItems.Add($@"Found and add VM -> View: {viewType.FullName} -> {vmt.Value.FullName}");
}
else
foundItems.Add($@"Pair is already known VM -> View: {viewType.FullName} -> {vmt.Value.FullName}");
}
}
return foundItems;
}
private static DataTemplate CreateTemplate(Type viewModelType, Type viewType)
{
// The only way to get around some problems with binding later is this way of creating datatemplate objects
// see www.ikriv.com/dev/wpf/DataTemplateCreation/
const String xamlTemplate = " ";
var xaml = String.Format(xamlTemplate, viewModelType.Name, viewType.Name);
var context = new ParserContext { XamlTypeMapper = new XamlTypeMapper(new String[0]) };
context.XamlTypeMapper.AddMappingProcessingInstruction("vm", viewModelType.Namespace ?? throw new InvalidOperationException(), viewModelType.Assembly.FullName);
context.XamlTypeMapper.AddMappingProcessingInstruction("v", viewType.Namespace ?? throw new InvalidOperationException(), viewType.Assembly.FullName);
caliburnmicro.com
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
context.XmlnsDictionary.Add("vm", "vm");
context.XmlnsDictionary.Add("v", "v");
var template = (DataTemplate)XamlReader.Parse(xaml, context);
return template;
}
DynamicVmTemplateFinder.GenerateTemplateDictionary(typeof(App), Current.Resources, Assembly.GetExecutingAssembly().GetTypes())
The Dictionary handles the mapping by binding the View and ViewModel together.
It became clear by June 2020, at the latest, that this was the right decision. At that time, the developer marked Caliburn.Micro as no longer maintained.
The reasons are often the same. There are only a few developers responsible for the project, and as their personal or professional circumstances change, they are often no longer able to continue development that is typically carried out in their spare time.

This example shows that the decisions and considerations made in this case resulted in the investment paying off. The freedom to make these decisions within the development team is a hallmark of working at OHB Digital Services.
There is a great deal of leeway for these decisions; team members can contribute their own ideas, and the project manager does not dictate which type of library should be used. Because decisions are made as a team, this often results in better solutions.
Over time, we’ve found that it often makes more sense to create our own solutions and develop a simple, small framework ourselves rather than using more complex third-party frameworks.
If you do decide to use a third-party library, however, you should always be aware that this isn’t a sure thing. Instead of simply integrating it and forgetting about it, a high level of care and maintenance is essential even with third-party software. As the number of dependencies increases, it’s easy to lose sight of hidden incompatibilities. This can also lead to time-consuming bug fixes if the third-party software isn’t thoroughly understood. All of this must not be overlooked.
Ultimately, of course, the goal is to provide the best possible product for the customer, and decisions should be made with this in mind.
Leverage space technology for your business. OHB Digital Services GmbH has been a reliable partner for secure and innovative IT solutions for many years. We are part of one of the most successful aerospace and technology companies in Europe. With our products and services, we support you in areas such as the digital transformation of your business processes along the value chain and with all security-related issues. Please feel free to contact us.
Then please contact us.
You are currently viewing a placeholder content from Vimeo. To access the actual content, click the button below. Please note that doing so will share data with third-party providers.
More InformationYou are currently viewing a placeholder content from YouTube. To access the actual content, click the button below. Please note that doing so will share data with third-party providers.
More InformationYou need to load content from reCAPTCHA to submit the form. Please note that doing so will share data with third-party providers.
More InformationYou are currently viewing a placeholder content from reCAPTCHA. To access the actual content, click the button below. Please note that doing so will share data with third-party providers.
More InformationYou need to load content from hCaptcha to submit the form. Please note that doing so will share data with third-party providers.
More InformationYou need to load content from reCAPTCHA to submit the form. Please note that doing so will share data with third-party providers.
More InformationYou are currently viewing a placeholder content from Turnstile. To access the actual content, click the button below. Please note that doing so will share data with third-party providers.
More Information