Kategorier
software development Troubleshooting tutorials

C# dotnet standard and .Net Framework causing MissingMethodException in mscorlib

Brief

The Aspose.Email library is used to build emails and send using SMTP.

  • reason for using Aspose at first is that the project have the Aspose.Total license, including Email, and other Aspose libraries used for handling documents.

The Solution structure and implementation of Aspose.Email

  • ”EmailProcessor” a dotnet standard 2.0 Library implementing Aspose.Email
  • ”EmailProcessor.Test” a dotnet core 3.1 unit test project
  • ”WindowsService” a .Net Framework (4.8) service project;
    Framework and not dotnet core, is decided due to the environment. However, the Library (EmailProcessor) was supposed to be in dotnet standard.

In EmailProcessor I have a wrapper class, EmailDispatcher, calling the Aspose smtp client to send email.

The following is the code of interest.

//inside the using class, lets call it EmailConsumer.cs
_emailDispatcher.SendEmail(context.ReplyMessage)
// inside EmailDispatcher.cs
await _smtpClient.SendAsync(message);

Hands on troubleshooting (i.e. banging my head in the wall)

While developing and debugging with my xUnit integration test (dotnet core project) everything runs fine. But when installing the windows service the process ends in EmailConsumer at the calling row _emailDispatcher.SendEmail(context.ReplyMessage)
when Debugging the windows server it takes some time to pinpoint this, and no exception is caught in my debugging (however, later on, I can correlate the following line in visual studio ”output” window)

  • Exception thrown: ’System.MissingMethodException’ in mscorlib.dll

With my emailDispatcher,
note: I assumed the debugger would take me inside the EmailDispatcher class and my breakpoint on ”smtpClient.SendAsync”, but (probably due to the class using Aspose.Email) I’m not able
to step into ”emailDispatcher.SendEmail”
the logged error, ’System.MissingMethodException’, is shown many times, therefore I was not sure if it had anything to do with the error I had, until I put a brakepoint on the row ”_emailDispatcher.SendEmail(context.ReplyMessage)”, and executed the same code in visual studio ”Immediate Window” ; that gave me a better detailed error message as below

Exception thrown: 'System.MissingMethodException' in mscorlib.dll
Method not found: 'System.Threading.Tasks.Task Aspose.Email.Clients.Smtp.SmtpClient.SendAsync(Aspose.Email.MailMessage)'.


   At EmailProcessor.Email.EmailDispatcher.<SendEmail>d__4.MoveNext() in C:\Git\EmailProcessor\Email\EmailDispatcher.cs:line 107
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine)
   at EmailProcessor.Email.EmailDispatcher.SendEmail(MailMessage message)

Stackoverflow to the rescue (?)

Some good answers for this type of error are found in this thread https://stackoverflow.com/questions/8058832/system-missingmethodexception-method-not-found

  • ”This is a problem which can occur when there is an old version of a DLL still lingering somewhere around. Make sure that the latest assemblies are deployed and no duplicated older assemblies are hiding in certain folders. Your best bet would be to delete every built item and rebuild/redeploy the entire solution.”
  • ”In particular, be sure an old version is not in the GAC”

So looking in GAC, the global cache, (run ”gacutil /l” in powershel for VS, to list all cached)

I realized Aspose libraries are not available in GAC (mostly Microsoft stuff here)

  • Double check, more than once, that nuget packages are correct (note: the windows service does not reference the Aspose libraries directly)
  • And once more validate I have the ”RestoreProjectStyle” set to PackageReference (see more on that issue in this github page , this can also be an issue when mixing dotnetstandard with .NET Framework
  • I Erase Bin and Obj folders for all projects and rebuild. (yeah, sometimes it’s just as simple)
  • Still not working

Now some more digging,
the SmtpClient (netstandard) decompiled looks like this.

// Decompiled with JetBrains decompiler
// Type: Aspose.Email.Clients.Smtp.SmtpClient
// Assembly: Aspose.Email, Version=20.1.0.0, Culture=neutral, PublicKeyToken=716fcc553a201e56
// Assembly location: C:\Users\Hemma\.nuget\packages\aspose.email\20.1.0\lib\netstandard2.0\Aspose.Email.dll
...

I confirm that the method, SendAsync, does exist;

  • sure I already knew this since I can use it while coding, but still. magic things and unicorns do exists in computers.
  • and I can use it with the real expected result when running from my xunit (dotnet core)

This is what SendAsync looks like in the decompiled code (just confirming what we know)

...
/// <summary>Send the specified message.</summary>
/// <param name="message">The MailMessage that represents an email-message.</param>
/// <returns>Task object, with delegate for this operation</returns>
public System.Threading.Tasks.Task SendAsync(MailMessage message)
{
...

However… since it does not work from my .Net Framework (4.8, or 4.7.2). and I get the error pointed out above. I installed the nuget package Aspose.Email in the windows service project, since this is also a known possible workaround when referencing dotnetstandard projects from .NET Framework

The ”last resort”, before changing things or removing Aspose.Email, is to try with the Aspoe.Email nuget package installed directly into the windows service project (.Net Framework).

  • the result is the same error, mscorlib MissingMethodException

Now.
Trying to use the the SendAsync method in the Windows Service (framework project) just to see what would happen
I could see that the APIs are not the same.
In the net40 framework version there is no ”SendAsync” method, however.. there is a ”BeginSend” method that is possible to use in a similar manner.

  • IAsyncResult asyncResult = _smtpClient.BeginSend(message);
    (also documented in https://github.com/aspose-email/Aspose.Email-for-.NET/blob/master/Examples/CSharp/SMTP/SendEmailAsynchronously.cs)
  • and this method, BeginSend, is available in the dotnetstandard version – BUT, marked as deprecated and is not as convenient to use.

Validating the correct version on file level, matching the version 20.1 used in the EmailProcessor Library ; here, decompiled inside the .NET Framework project
(notice that this is the ”net40” target and not the ”dotnetstandard”)

// Decompiled with JetBrains decompiler
// Type: Aspose.Email.Clients.Smtp.SmtpClient
// Assembly: Aspose.Email, Version=20.1.0.0, Culture=neutral, PublicKeyToken=716fcc553a201e56
// Assembly location: C:\Users\Hemma\.nuget\packages\aspose.email\20.1.0\lib\net40\Aspose.Email.dll

Worth noting,

is that the Api reference, at Aspose.com, actually does not display the async methods, if it is by intention or not I do not know.
And, none of the examples in the Github repo shows the SendAsync method. – however, the examples are from up to 2018, and might be outdated)
https://apireference.aspose.com/email/net/aspose.email.clients.smtp/smtpclient/methods/send/index
https://github.com/aspose-email/Aspose.Email-for-.NET/tree/master/Examples/CSharp/SMTP

Final thoughts and lessons learned.

  • Look for exceptions even if things seem to work.
  • Use the Debug -> Windows -> Modules (available when debugging) to see where the assembly was loaded from.
  • If you are mixing different frameworks,
    check if there are differences in dependendent API implementations targeting the different frameworks (e.g. neststandard, net40)

Solution / Workaround

As a first workaround for this error I replaced ”SendAsync” with the ”Send” method (available in both netstandard and net40 Api) wrapped in a Task.

//does not work.
//await _smtpClient.SendAsync(message);

await Task.Run(() =>
    {
        _smtpClient.Send(message);

    }, cancellationToken);
  • This might be good enough.

But perhaps I will use MailKit https://github.com/jstedfast/MailKit instead (open source with good documentation and working examples),
I already switched to ImapClient from MailKit since it was smoother to use and with cancellation and had a good code example for IMAP Idling.
But I already use Aspoe to build email message, and that might need to be changed of changing the smtp sender (perhaps it’s easy to convert he message between the libraries as a mime stream).

Thats all, I hope this points you in a direction to solve whatever problem you have

assuming you don’t read things like this for fun 😉

Kategorier
Business Learning Meaningful Work and Life product development software development

What I talk about When I talk about software development (part 1)

A Brief of My Thoughts and Beliefs regarding development of software – and other things.

January 2020, a winter resembling a mix of late autumn and early spring (stretching February – why is it so hard to finish this article? 😊
Finishing off, end of August, it was a long summer “holiday”, and now the need to transfer the writings from Word into wordpress, always a pain, another obstacle to fight..

Apart from being a believer in test driven design, quick feedback loops and delivery of real value…
I believe in Magic.

Reading and understanding; the article “Programming as Theory Building – by Peter Naur”, the book “Design Thinking – by David West & Rebecca Rikner”, the concepts of “Mob programming – by Woody Zuill” and “Domain Driven Design – by Eric Evans”, pretty much sums up my core beliefs regarding development of software, systems, products and teams.

Perhaps the most important, in software products, is to create a ubiquitous language, connecting business and programmers with a common understanding of the domain, pushing the development into the domain knowledge space; with this in place there is a good chance of doing the right thing.

All above, together with the many other optional tools born in the thriving community around DDD Europe – I am convinced magic things will happen.

Thoughts

  • Software development – is all about the outcome based on the theories built by one or more persons, often a team; a team is all the people involved, such as experts, developers/programmers, users and other stake holders that can affect the team and the product.
  • The actual fit – of the outcome of an implementation in the real world, is highly effected by the designers understanding of the problem space, the current system and the wanted state, and the designers abilities and his intentional alteration of that system by adding, removing or changing some part(s) while hoping for the intended outcome.

    The question of when and how well a solution fits, hints that short feedback loops are extremely important during the design, prototyping and implementation of a system – unfortunately many teams don´t work with feedback until they deliver a “ready to ship” product or feature.
  • Mob programming could be compared to modern processors with multiple cores. A single brain does not have the same capacity, for thinking and exploring, as two or more brains do; therefore, I see this as a fundamentally better way to do qualitative knowledge work, while also gaining social stimuli, and providing a more challenging and creative environment.

    I believe one of the reasons we left the mob programming style in favour for individual work is due to management seeing software production as something that can be broken up to a manufacturing production line, and when computers became less expensive than people this was a natural step in the “factory setup”; this is in many ways how “teams” work today, even “agile” teams, with a Kanban board and tickets for as small tasks as possible, sometimes even broken up by “upper level people”.
  • Trust – the more we know the people we work with on a personal level, the more we trust them for their proven track record; working in tight teams forces you to become closer.
  • Flow – according to science, the most fulfilling type of flow is achieved in collaboration, like in a football team or solving problems together with colleagues. I believe it is also easier to maintain a flow state in a group of engaged people, than when working alone – especially if working “alone” in an open plan office
  • Magic teamwork – when work becomes teamwork, work becomes play; when work is play, work becomes fun; when work is fun people get on fire; when people get on fire by doing work they love – magic things starts to happen. I want magic teamwork in any game I play.

Design thinking.

Reading “Design thinking – The key to enterprise agility, innovation and sustainability”, by David West and Rebecca Rikner gave me an awakening, of some kind, realizing who I am and what lights my fire.

I have always loved to understand how things work, fascinated by the beauty of nature and in love with functional design. Being creative with my hands since childhood, forming for usability or mimicking nature, I guess other paths could have led me to become a carpenter or architect (of buildings).

This is me, Design Thinking + IT Thinking + Business Thinking

When I opened this page, it was like Dave had picked my brain and soul and found my core interests, background and future.

An “explanation” of the mapping I see when I read this picture…

A former colleague told me “you are an organizational genius – that’s just how it is”, others have said “You are extremely quick in picking up and understand the core of the overall system”.

I studied to become avionics engineer and liked the idea of fixing airplanes but didn’t love it, so I moved on.

I have studied business finance and liked the accounting but loved the marketing and had fun, with my friend, creating print and web marketing for restaurants and nightclubs – and a golf course panorama overview (long before street maps).

I have studied history of arts and design, materials and production techniques, and liked the ideas of Lean manufacturing but loved the creative process of product design with brand recognition.

I have worked in many non-IT related areas such as mechanics, manufacturing, sales, support, warehouses, and in a variety of IT related areas such as tech support, infrastructure (servers, network etc.), and since 2013 in different software development teams, mainly in product companies but also as consultant.

Wherever I have been, I have seen ways to improve things, like management, the way of working or the physical working environment – in most of the places I have left a footprint, either by changing a process, way of working, or at least by challenging the ways of doing things. If needed I also act as a secret janitor to fix or improve things at the physical work place just because I care about my environment (have problems with broken and filthy things, not OCD but probably closer than many 😉)

I need to feel joy and ease in my working environment

A brief overview of the contents in the book Design Thinking

To be continued… part 2 in this context is about ”Teams – and groups”

Kategorier
product development software development

Modeling and mapping tools

This is a living document with tools I find useful for modeling and mapping.

Wardley maps – gives a broad pitcure, overview; mapping user needs we want to address and the underlying components needed to fulfill those needs, each need has it’s own needs and we can show abstract or more detailed levels to understand what the whole system needs – example – a city , roads, electricity, water, etc.. or zoomed in on a smaller thing,

this is a good start to talk around with investors and partners, and to understand if this is something you really want to do (is it worth it, can you buy it, are there to many competitors)

David (Dave) West’s (has, is, can have..) diagram – gives an abstract but connected, and if wanted, detailed map of connected parts in a complex system (f ex. Ultra Large Scale Adaptive Complex Systems) – this gives a good overview of needs for different parts of the system. (todo: add example here)

Adam Dymitruk – Event Modeling – a blueprint tool to map out what needs to happen in the system on different levels , visualizing user roles and different supporting services needed – and how they are interconnected with business events.

David Snowden – Synefin – to position your problem space and solution space on a levels of complexity and uncertainty (some overlap with Wardley maps)

Kategorier
Business Learning product development software development Tools

Why Maps? Why Wardley Maps?

Why (Wardley) Maps?

In short; because if you have a map you have a context and it gives you situational awareness – without a map to navigate your business, or personal, goals you are probably walking in a dark room with the light of a matchstick – with a map you are walking in the same dark room, but holding a flashlight; giving you the opportunity to be aware of the space you are in. Having situational awareness is a strategic advantage over those who don’t, probably most companies and organization, but more importantly you have the opportunity to actually find new paths or new ways to travel on your map; or how to even redraw the map as you would like it to bee or how the future would look like.

a map gives you situational awareness, making you aware of the space you are in

A real world map example.

Imagine you are going, by car, from Stockholm in Sweden to Helsinki in Finland – you know you need a car, to explore some areas and cities around Helsinki, and to visit a friend in Lahti; about two hours north of the capital.

Without a map and no experience of the route you are likely to depend on asking people on your way there, if you are lucky you get good directions, and don’t have to stop too many times asking for new.

Now, here is a map for you, with the major roads and some water routes plotted. Depending on your needs you could now think of two ways to travel, the first and perhaps most obvious is to go by car around the water (a drive taking about 20-21 hours non stop), the second way would be to go over the water, but then you need a boat, and you must be able to take your car on the boat, but you don’t have access to a boat and are not comfortable with the idea of sailing; the drive of 20 hours seems like the best option.

But, then you meet someone, like me, you show me the map and talk about your travel plans.

me: – ”that sounds like a fun trip, are you going to see anything special up north? Like the polar light or playing golf in Tornio with 11 holes in Sweden and 7 in Finland !? ~I would like to to do that too!”
you: ”no, didn’t plan that, I just want to see Helsinki and meet a friend a couple of hours north from there”
me: ”I see, but.. why don’t you take the ferry then? you can sleep, eat, relax and even get a SPA treatment if you like while going there, I mean, instead of driving all the way”
you: ”Oh.. is there a ferry line? that sound like a better option”

me: ”definitely, and yet another option is to go by air and rent a car, or perhaps your friend has a car to borrow while you are there.”
you: ”didn’t think of that, but I’ll take the ferry, it’s definitely the best option for this trip. Thanks!”

Lesson learned: Having a map to show others and talk about makes things super clear

What could the future look like on the map?

Imagine all the things possible and not really possible to explore what might be in a future, near or distant.

Could there be a tunnel under the Baltic Sea? (Östersjön) or a bridge crossing it? Or perhaps the sea could dry out? Or the lands be extended into the sea? Or a massive earthquake could move the countries together?

If you have a map it is easy to start adding layers of ideas and to test concepts in the context of the map.

REMEMBER – on a map, the space has meaning, and you might think of the space as being an obstacle, but know that the obstacle often is the way – ”every obstacle is an opportunity in disguise

On Wardley Maps, mapping businesses, products and perhaps your personal future and current situation read this article with resources.

Kategorier
CQRS event-sourcing Learning software development

Commands and commandHandlers

CQRS and Event sourcing – Resources

When looking at this video walk-through of OAuth Event Modeling in Go by Jamie there was a question about how to handle commands without the need of switches over the command types.

So my reply on that got a little longer and thought I would share the resources I pointed to here (to free the comment from being stuck in youtube)

Great example and walk through Jamie! (and thanks to the rest of you for value provided)

Regarding handling events without the switch, I do not know Go – but in C# you usually register EventHandlers with commands and you will have a dispatcher or similar as a single entry point where the handlers knows what commands they should act on. see examples in referred links below.

So, maybe this is not for Go devs, but you might get some ideas from it, anyhow.. here are some links for c# resources.

SuperSafeBank

”This repository shows how to implement Event Sourcing, CQRS and DDD in .NET Core, using a Bank as example.”

This (C#) repository looks like a great example application ( a little more complexity, I haven’t dived deep into it yet) https://github.com/mizrael/SuperSafeBank

CQRS in Practice (course and code)

Vladimir Khorikov, my go to guy when looking for quality examples, and learning the craft in C#, shares some high quality stuff (pluralsight corses and blog https://enterprisecraftsmanship.com/posts/types-of-cqrs/)

In this repository, https://github.com/vkhorikov/CqrsInPractice/blob/master/After (from the Pluralisght course CQRS in Practice) – you can see an implementation example; I’ll try to flesh out the command and commandhandler stuff for you here.

I like to look at things in the order of ”from entry point in the API”, Hope you can follow my logic =)

Command to Result flow.

API

start in ’Api\Controllers\StudentController.cs’.Register(…)

//called from UI to register student
Register(NewStudentDto dto)
            var command = new RegisterCommand(...); // (Logic\AppServices\RegisterCommand.cs)
            Result result = _messages.Dispatch(command); //finds handler, handles the command and returns the result.

The message Dispatcher

in ’Logic\Utils\Messages.cs’

in ’Messages.Dispatch(command)’ the matching handler for the command is looked up, via DI, and then executed (aka handled).

handler = _provider.GetService(handlerType); // System.IServiceProvider (built in)
result = handler.Handle(command);

The Registration of handlers

Startup.cs

DI, Dependency Injection, is configured in ’API\Startup.cs’ and handlers, for commands and queries; these are registered via services.AddHandlers() – where ’services’ is ’Microsoft.Extensions.DependencyInjection’

HandlerRegistration

’Api\Utils\HandlerRegistration.cs’.AddHandlers()

  • This class takes care of finding, and registering, all handlers of type ICommandHandler and IQueryHandler in the assembly,
  • making them available for use from IServiceProvider.GetService(serviceType)

Kategorier
event-sourcing Learning software development tutorials Uncategorized

EventStore(DB) Getting Started

https://github.com/JimiSweden/eventstore-getting-started

Here is the repository for my getting started project following the guide from eventstore.com

To be continued… Eventually

Kategorier
event-sourcing product development software development Uncategorized

Brick by brick

Brick by brick, piece by piece, part by part – anything an object? anything an event?

What if.. you did lay out the bricks in a good way, to support the small house you started to build, but then decided you should widen your house, or perhaps make it taller, and just started over – brick by brick. This might be hard, probably to expensive, but possible, in the brick house world. Sure, some of the events bricks might be broken and, thrown away, replaced by new ones.

In the software world it often gets to messy and expensive, but can many times be a lot easier than in the physical world. Since we, in an event sourced system, could tear down the brick wall (our UI data projection), and replace all bricks (i.e. events) in the places we want them for our new building.

I have a simple challenge for you

Think of anything in the world and try to convince me it is not a result of events from the past.

if you did come up with something, please write on LinkedIn in this post

So, last week I restarted my learning path of event sourcing and eventstore, and today I happened to stumble on this post  https://eventstore.com/blog/event-sourcing-and-cqrs/ by @AlexeyZimarev – I can highly recommend it as an introductory article on event sourcing and cqrs (pointing at eventstore with some examples) + DDD talks from Alexey.

I was not about to write an article but since I had to much text for a simple post on LinkedIn I expanded 🤠

I’m familiar with the concept of event sourcing and believe most systems should use it, but haven’t worked with it for 3 years and wasn’t fluent then; now I need to learn it solidly for a personal project and also to evolve as a software developer.

Why event sourcing? What is it good for? You want the truth?(Pi)

If you are a developer and not familiar with event sourcing you should update yourself.

a 6 minute answer of why event sourcing by Alexey – in short; it enables you to know what has happened in the past which enables troubleshooting and capitalization of user behavior etc, the historical data is not destroyed as in a ”state managed system”, i.e. traditional CRUD, and thus you always have the truth.

The power of events is unlimited compared to traditional crud systems.

Events are not new in the software world, but for a long time too many systems have suffered from not having an event based implementation.

Your bank account transaction history is perhaps the most publicly known example of event sourcing – all historical events builds the current balance (history is complete).

From a technical perspective

maintenance and support in state managed vs event sourced systems.

Troubleshooting and support in a STATE managed system.

In the development phase when defects are found and no one knows what happened and the original data is overwritten by the defect but you don’t know it did – it gets hard to find the issue. Or worse, the defect gets shipped and destroys data at a customers site and you can’t restore the data, you can’t see if the system caused it or if the customer has changed the data.

Support – without the possibility to see what happened, in the system before it got to a ”broken” state, it takes a lot of effort to track what has changed and by who, and users might not know or remember, or don’t dare to tell the truth. If you have great logging in place, you might be able to track changes that way – but it’s often not efficient, if at all possible.

Troubleshooting and support in an EVENT sourced system

Troubleshooting in development and support; since you have access to all events, you can look at all events in the time between a last known good state and the broken state, you can see what really did happen, and what or who caused it, and when.

For difficult support cases it becomes possible to take a database from a production system in a broken state, replay all events (i.e. rebuilding the state from history) and observe what happens – just like following a rope from end to end, instead of wrestling in a big ball of mud or looking for a needle in a hay stack.

would you rather untangle the rope or go looking for the needle in the haystack?

Aligned with the real world languages and human thinking

Perhaps the greatest power is that events are natural for our minds, and something I could talk to my mum about (she doesn’t really understand what I mean when I say web browser).

Stories are made of events  

as am I, so are You, as are the history of life

Humans are exceptionally good at remembering stories, stories are made of events, as am I, so are You, as are the history of life. 

So, talking with users, domain experts, developers etc. becomes easier – developers can learn the actual business process and language much faster and actually talk to non technical people (at least some.. I can 😉) about what is going on in the code. 

Product and business life cycle – room for evolving and improving together.

Projected read models, f ex for display to users or other systems, becomes easy to alter and make variations of as the system grows and business evolves, as the business thinks of new concepts.

Adding new types of events and letting other systems listen to event changes gets easy.

Business intelligence (i.e. tracking what happened and when) becomes easy, having insight in how customers and the user behaves is very valuable for improving the software and the business drivers. Storing the source of truth enables business to reuse the data in not yet known ways.

Getting new team members up to speed on how the system behaves is easier when events can be lined up in an overview.

Combine event storming, to understand the important things of the domain in collaboration of domain experts and software developers, with domain story telling, to find important concepts, use cases and user interactions/flows; and then map them to an eventmodeling system blueprint – readable by most people (at least with a brief explanation)

And now ”all” you need to do is to build the software (using TDD and DDD in a mobprogramming team – IMHO)

Recommended links

https://eventmodeling.org/posts/what-is-event-modeling/
https://www.eventstorming.com/
Domain Story Telling
MobProgramming intro
Domain-Driven Design Europe – many good talks on software development
Visual Collaboration Tools is a (free) book for software engineering teams. ”It describes tools that help us in our daily job, and also present field stories from different practitioners.”

#eventstore #eventsourcing #eventmodeling #eventstorming #systemchange #ModernSoftware #MakeItEasy #BusinessIntelligence #BI softwaredevelopment #productdevelopment #businessdevelopment