This time i am trying to port a .NET Framework project working in Windows and Visual studio 2019 to .Net Framework project working on Mac and Visual studio for Mac 2019. It can be compiled on top of the mono framework for .NET but running parts of it is still a challenge. But when doing work on that, i realised few mistakes people do and thought i will highlight them.

Type usage and References

TL;DR

We use types outside of their assembly more liberally than we actually should. Because these kind of usage  create a strong coupling in code that makes it rather difficult to decouple over time. And one such example is using the IDependencyResolver class instance in our test projects.

The longer story

One of the assemblies (`System.Web.Http`) is heavily used in our test projects and i don't understand it's usage. So i went into it in an  attempt to make the code better.

The System.Web.Http assembly is used by many Test projects. My initial guess was using it to support  API client calls, but it turns out i am wrong. We are using it solely to resolve the type IDependencyResolver which is used in the following code fragment in tests. Based on reference count in 30 places in almost all test assemblies.

       1 [OneTimeSetUp]
       2 public void SetUp()
       3 {
       4     Bootstrapper.Initialize();
       5     if (ObjectFactoryAdapter.Current == null)
       6     {
       7         service = ObjectFactoryAdapter.GetInstance<IMemberNetworkService>();
       8     }
       9 }

In the above code fragment in Line number 5, the Current property is an instance of IDependencyResolver which is an interface defined in System.Web.Http assembly .

I removed the check and rewrite the code as follows

       1 [OneTimeSetUp]
       2 public void SetUp()
       3 {
       4     Bootstrapper.Initialize();
       5     service = ObjectFactoryAdapter.GetInstance<IMemberNetworkService>();
       6 }

And removed the reference for System.Http.Web. The project compiled succesfully. The message here is Don't let your types flow from one assembly into another and create dependency with multiple other types / assemblies. We added a package reference to almost all the test projects because we need to resolve this one type. Please be careful in using types outside of the class. These will create coupling to other parts of code. Now to properly rewrite the first fragment, i did this

Goto ObjectFactoryAdapter.cs and add the following

public static bool HasCurrent()
{
    return Current != null;
}

and in all the test projects remove the reference to System.Http.Web and substituted the following code instead

       1 [OneTimeSetUp]
       2 public void SetUp()
       3 {
       4     Bootstrapper.Initialize();
       5     if (ObjectFactoryAdapter.HasCurrent())
       6     {
       7         service = ObjectFactoryAdapter.GetInstance<IMemberNetworkService>();
       8     }
       9 }

Now since the type is not referenced in this assembly, the C# compiler won't attempt to prompt for a compile time reference. Even during runtime this method doesn't try to resolve IDependencyResolver but the assembly that has ObjectFactoryAdapter would take care of.

Platform independent Build events

Whenever you write build events , first think if you really need it. If you cannot live with it then go ahead and write. But when writing them, make sure they run in all environments. Developer, Build, and other platform considerations. the copy command below will pretty much fail for everything except windows. Another problem with these are the difficulty with debugging. The only result will be the comamnd failed with error -(some number).  So avoid using shell / cmd commands or even powershell or other scripts. Instead use MSBuild native  code.

copy /Y "$(SolutionDir)Service\***\Templates\cda.xsl" "$(TargetDir)Content\Templates\"

The above can be rewritten as follows

   <Target Name="AfterBuild">
      <ItemGroup>
          <CCDXslFile Include="$(SolutionDir)Service/***/Templates/cda.xsl" />
      </ItemGroup>
      <Copy SourceFiles="@(CCDXslFile)" DestinationFolder="$(TargetDir)/Content/Templates/" />
   </Target>

Project type guid's not supported are removed.

VS Project guid  for testing is {3AC096D0-A1C2-E12C-1390-A8335801FDAB}. This is not supported anymore in VS for Mac and not required for future version of visual studio 2019. Test projects are basically C# projects and IDE's discover them automatically using the test attributes. We need NUnit extension in visual studio though for this to work. The new project type guid is supported by Visual Studio in windows as well.