.net core中實現服務自動發現

.net core中自帶了依賴注入框架,asp.net core或worker框架下可以直接使用, 控制檯程序可以通過加入Microsoft.Extensions.DependencyInjection程序包來支持。自帶的di框架功能還行, 但是一個不方便的地方是沒有提供服務自動發現、註冊的接口,稍微大的程序都是需要通過反射自己寫一個發現程序的。

今天網上找到了一個第三方實現的服務發現的庫Scrutor,還比較好用, 示例如下:

var collection = new ServiceCollection();

collection.Scan(scan => scan
     // We start out with all types in the assembly of ITransientService
    .FromAssemblyOf<ITransientService>()
        // AddClasses starts out with all public, non-abstract types in this assembly.
        // These types are then filtered by the delegate passed to the method.
        // In this case, we filter out only the classes that are assignable to ITransientService.
        .AddClasses(classes => classes.AssignableTo<ITransientService>())
            // We then specify what type we want to register these classes as.
            // In this case, we want to register the types as all of its implemented interfaces.
            // So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
            .AsImplementedInterfaces()
            // And lastly, we specify the lifetime of these registrations.
            .WithTransientLifetime()
        // Here we start again, with a new full set of classes from the assembly above.
        // This time, filtering out only the classes assignable to IScopedService.
        .AddClasses(classes => classes.AssignableTo<IScopedService>())
            // Now, we just want to register these types as a single interface, IScopedService.
            .As<IScopedService>()
            // And again, just specify the lifetime.
            .WithScopedLifetime()
        // Generic interfaces are also supported too, e.g. public interface IOpenGeneric<T> 
        .AddClasses(classes => classes.AssignableTo(typeof(IOpenGeneric<>)))
            .AsImplementedInterfaces()
        // And you scan generics with multiple type parameters too
        // e.g. public interface IQueryHandler<TQuery, TResult>
        .AddClasses(classes => classes.AssignableTo(typeof(IQueryHandler<,>)))
            .AsImplementedInterfaces());

這個類本身是比較好用的,但是它仍需要手工制定程序集作爲掃描範圍。 這個程序集的範圍並不是所有程序集,往往只有用戶代碼程序集, asp.net core程序內部是有這個功能的,例如它內部就能掃描所有用戶程序集,生成ApiController,網上搜了一下,發現還是一個內部接口,不過可以通過反射來調用:

	public static Assembly[] GetAssemblies()
	{
		var manager = new ApplicationPartManager();

		var method = manager.GetType()
		                    .GetMethod("PopulateDefaultParts",
			                     BindingFlags.NonPublic | BindingFlags.Instance);


		//加載入口程序集的依賴項樹中的所有非官方包的依賴程序集
		var assembly = Assembly.GetEntryAssembly().FullName;
		method.Invoke(manager, new object[] { assembly });

		return manager.ApplicationParts.OfType<AssemblyPart>().Select(i => i.Assembly).ToArray();
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章