NancyFx / Nancy

Lightweight, low-ceremony, framework for building HTTP based services on .Net and Mono
http://nancyfx.org
MIT License
7.15k stars 1.47k forks source link

Assemblies branded with IncludeInNancyAssemblyScanningAttribute and other essential Nancy assemblies aren't getting cataloged. #2956

Open fartwhif opened 5 years ago

fartwhif commented 5 years ago

@tpluscode This is the same for all Nancy projects - DNX or not. Nancy won't scan assemblies not referencing Nancy.dll by default. If you don't reference the dll or not using any Nancy code in your library at compile-time (which makes the compiler strip the reference), it won't be picked up by default. We even added the [assembly: IncludeInNancyAssemblyScanning] attribute just for this scenario.

Also, there's no hardcoded path that Nancy scans. It looks at AppDomain.CurrentDomain.SetupInformation.ApplicationBase and AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, so AFAIK this works on DNX451 as well šŸ˜„

Originally posted by @khellang in https://github.com/NancyFx/Nancy/issues/1959#issuecomment-145452163

I was able to get my plugin architecture for a .Net Core 2.1 application to work, one of the plugins includes Nancy/OWIN/Kestrel but Nancy can't find the NancyModule types in the plugin assembly because the main assembly, which is loading the plugin assembly during runtime, does not reference anything in any plugin, so I had to perform the following patch, and I noticed that current master branch of Nancy doesn't actually utilize the helper attribute IncludeInNancyAssemblyScanningAttribute so I thought I would leave this here in case it helps others with this problem. Using the code [assembly: IncludeInNancyAssemblyScanning] in the plugin's assemblyinfo.cs Nancy scans the plugin assembly and finds the NancyModule types, with the following patch.

edit: I found that Nancy.Validation.FluentValidation assembly (and others probably) even when loaded in current application domain, since the entry assembly is not referencing it, in this "plugin scenario", is not cataloged either. It requires some extra spice during run-time before Nancy startup, and the extra condition in the cataloger. Interestingly, Nancy.Authentication.Stateless seems to be immune from this "disconnection" problem.

Pre-Nancy-startup during runtime:

    // loads Nancy.Validation.FluentValidation assembly into the current app domain so that the patched DependencyContextAssemblyCatalog will catalog it upon startup
    var z = new DefaultFluentAdapterFactory(null);

patch to Nancy:

     src/Nancy/DependencyContextAssemblyCatalog.cs | 1 +
     1 file changed, 1 insertion(+)

    diff --git a/src/Nancy/DependencyContextAssemblyCatalog.cs b/src/Nancy/DependencyContextAssemblyCatalog.cs
    index f62b4d67..b8203661 100644
    --- a/src/Nancy/DependencyContextAssemblyCatalog.cs
    +++ b/src/Nancy/DependencyContextAssemblyCatalog.cs
    @@ -56,6 +56,7 @@ namespace Nancy
                     }
                 }

    +            AppDomain.CurrentDomain.GetAssemblies().Where(k => k.GetCustomAttributes(typeof(IncludeInNancyAssemblyScanningAttribute), false).Any() || k.GetName().Name == "Nancy.Validation.FluentValidation").ToList().ForEach(k => results.Add(k));
                 return results.ToArray();
             }