forked from autofac/Examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
78 lines (73 loc) · 3.86 KB
/
Copy pathProgram.cs
File metadata and controls
78 lines (73 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using Autofac;
using Autofac.Configuration;
using ConfigurationExampleInterface;
using Microsoft.Extensions.Configuration;
namespace ConfigurationExample
{
public class Program
{
/* Plugins and configuration can be challenging to figure out in .NET Core since assembly
* loading and type handling has slightly changed. This example shows how to use configuration
* to selectively load things. Additional examples and resources:
* - Unit tests for Autofac.Configuration: https://github.com/autofac/Autofac.Configuration/tree/develop/test/Autofac.Configuration.Test
* - Documentation for Autofac.Configuration: https://autofac.readthedocs.io/en/latest/configuration/xml.html
*
* To avoid referencing the external plugin assembly, the solution has a build dependency on the ConfigurationExamplePlugin
* project and this project uses a post-build copy to get the plugin assembly into the ConfigurationExample bin directory.
*/
public static void Main(string[] args)
{
// THIS IS THE MAGIC!
// .NET Core assembly loading is confusing. Things that happen to be in your bin folder don't just suddenly
// qualify with the assembly loader. If the assembly isn't specifically referenced by your app, you need to
// tell .NET Core where to get it EVEN IF IT'S IN YOUR BIN FOLDER.
// https://stackoverflow.com/questions/43918837/net-core-1-1-type-gettype-from-external-assembly-returns-null
//
// The documentation says that any .dll in the application base folder should work, but that doesn't seem
// to be entirely true. You always have to set up additional handlers if you AREN'T referencing the plugin assembly.
// https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/corehost.md
//
// To verify, try commenting this out and you'll see that the config system can't load the external plugin type.
var executionFolder = Path.GetDirectoryName(typeof(Program).Assembly.Location);
AssemblyLoadContext.Default.Resolving += (AssemblyLoadContext context, AssemblyName assembly) => context.LoadFromAssemblyPath(Path.Combine(executionFolder, $"{assembly.Name}.dll"));
var config = new ConfigurationBuilder()
.AddJsonFile("autofac.json")
.Build();
var configModule = new ConfigurationModule(config);
var builder = new ContainerBuilder();
builder.RegisterModule(configModule);
var container = builder.Build();
try
{
// Always resolve from a scope.
// https://autofac.readthedocs.io/en/latest/best-practices/index.html#always-resolve-dependencies-from-nested-lifetimes
using (var scope = container.BeginLifetimeScope())
{
var plugin = scope.Resolve<InternalPlugin>();
Console.WriteLine("Resolved specific plugin type: {0}", plugin.Name);
Console.WriteLine("All available plugins:");
var allPlugins = scope.Resolve<IEnumerable<IPlugin>>();
foreach (var resolved in allPlugins)
{
Console.WriteLine("- {0}", resolved.Name);
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine("Error during configuration demonstration: {0}", ex);
}
if (Debugger.IsAttached)
{
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
}