< Summary

Information
Class: MyNet.UI.Locators.ServiceCollectionExtensions
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/Locators/Extensions/ServiceCollectionExtensions.cs
Tag: 323_28699572109
Line coverage
60%
Covered lines: 12
Uncovered lines: 8
Coverable lines: 20
Total lines: 107
Line coverage: 60%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddViewLocators(...)100%11100%
AddViewNamingConvention(...)100%210%
AddNamespaceConvention(...)100%210%
AddParentNamespaceConvention(...)100%210%
AddAssemblyRootConvention(...)100%210%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/Locators/Extensions/ServiceCollectionExtensions.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ServiceCollectionExtensions.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using Microsoft.Extensions.DependencyInjection;
 9using Microsoft.Extensions.DependencyInjection.Extensions;
 10using MyNet.UI.Locators.Conventions;
 11using MyNet.UI.Locators.Factories;
 12
 13#pragma warning disable IDE0130
 14namespace MyNet.UI.Locators;
 15#pragma warning restore IDE0130
 16
 17/// <summary>
 18/// Extension methods for registering the Locator system into a <see cref="IServiceCollection"/>.
 19/// </summary>
 20public static class ServiceCollectionExtensions
 21{
 22    /// <summary>
 23    /// Adds the Locator system to the DI container, including default naming conventions, resolver, locators and factor
 24    /// </summary>
 25    extension(IServiceCollection services)
 26    {
 27        /// <summary>
 28        /// Registers Locator services: <see cref="SuffixConvention"/> (default), <see cref="ITypeResolver"/>,
 29        /// <see cref="IViewLocator"/>, <see cref="IViewModelLocator"/> and <see cref="IViewFactory"/>.
 30        /// <para/>
 31        /// Additional layout strategies are opt-in: <see cref="AddNamespaceConvention"/>,
 32        /// <see cref="AddParentNamespaceConvention"/>, <see cref="AddAssemblyRootConvention"/>.
 33        /// <para/>
 34        /// The optional <paramref name="configureResolver"/> callback is called after the resolver has been built, allo
 35        /// type registrations (e.g. <c>resolver.Register(typeof(MyViewModel), typeof(MyView))</c>).
 36        /// </summary>
 37        /// <param name="configureResolver">Optional callback to register manual mappings on the resolver.</param>
 38        /// <returns>The same <see cref="IServiceCollection"/> for chaining.</returns>
 39        public IServiceCollection AddViewLocators(Action<ITypeResolver>? configureResolver = null)
 40        {
 41            // Default: SuffixConvention handles ViewModels/Views segment swap and multiple view suffixes.
 1242            services.TryAddEnumerable(ServiceDescriptor.Singleton<ITypeNamingConvention, SuffixConvention>());
 43
 44            // --- Resolver ---
 1245            services.TryAddSingleton<ITypeResolver>(sp =>
 1246            {
 1247                var conventions = sp.GetServices<ITypeNamingConvention>();
 1248                ITypeResolver resolver = new TypeResolver(conventions);
 1249                configureResolver?.Invoke(resolver);
 1250                return resolver;
 1251            });
 52
 53            // ViewLocator: DI-first, fallback to Activator.CreateInstance for views not registered in DI.
 1254            services.TryAddSingleton<IViewLocator, ViewLocator>();
 55
 56            // ViewModelLocator: strict DI only — view models must be explicitly registered.
 1257            services.TryAddSingleton<IViewModelLocator, ViewModelLocator>();
 58
 1259            services.TryAddSingleton<IViewFactory, ViewFactory>();
 60
 1261            return services;
 62        }
 63
 64        /// <summary>
 65        /// Adds a single extra naming convention to the resolver chain.
 66        /// Call before <see cref="AddViewLocators"/> for higher priority, or after for lower priority.
 67        /// </summary>
 68        /// <typeparam name="TConvention">The convention implementation type.</typeparam>
 69        /// <returns>The same <see cref="IServiceCollection"/> for chaining.</returns>
 70        public IServiceCollection AddViewNamingConvention<TConvention>()
 71            where TConvention : class, ITypeNamingConvention
 72        {
 073            services.TryAddEnumerable(ServiceDescriptor.Singleton<ITypeNamingConvention, TConvention>());
 074            return services;
 75        }
 76
 77        /// <summary>
 78        /// Adds <see cref="NamespaceConvention"/> (ViewModels/Views segment swap, <c>*View</c> suffix only).
 79        /// </summary>
 80        public IServiceCollection AddNamespaceConvention()
 81        {
 082            services.TryAddEnumerable(ServiceDescriptor.Singleton<ITypeNamingConvention, NamespaceConvention>());
 083            return services;
 84        }
 85
 86        /// <summary>
 87        /// Adds <see cref="ParentNamespaceConvention"/> (views under <c>{Parent}.Views</c>).
 88        /// </summary>
 89        public IServiceCollection AddParentNamespaceConvention()
 90        {
 091            services.TryAddEnumerable(ServiceDescriptor.Singleton<ITypeNamingConvention, ParentNamespaceConvention>());
 092            return services;
 93        }
 94
 95        /// <summary>
 96        /// Adds <see cref="AssemblyRootConvention"/> with a configurable sub-namespace.
 97        /// Useful when views live under <c>{AssemblyName}.&lt;subNamespace&gt;.{Name}View</c>.
 98        /// </summary>
 99        /// <param name="subNamespace">The sub-namespace segment for views (default: <c>"UI.Views"</c>).</param>
 100        public IServiceCollection AddAssemblyRootConvention(string subNamespace = "UI.Views")
 101        {
 0102            services.TryAddEnumerable(ServiceDescriptor.Singleton<ITypeNamingConvention>(new AssemblyRootConvention(subN
 0103            return services;
 104        }
 105    }
 106}
 107