2

I am using Sitecore 8.2 Update 4 with Helix framework also using Microsoft Extension Dependency Injection. I have performed few steps for DI: 1. Created DI project in Foundation layer. 2. I have created on pipeline with name Habitat.Foundation.DI.RegisterControllers inside App_config/Include/zFoundation

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"><sitecore>  <services> <configurator type=" Habitat.Foundation.DI.RegisterControllers, Habitat.Foundation.DI" /></services></sitecore></configuration>

namespace Habitat.Foundation.DI{   public class RegisterControllers : IServicesConfigurator
{
    public void Configure(IServiceCollection serviceCollection)
    {
        serviceCollection.AddMvcControllers("*.Feature.*");
    }
}}

namespace Habitat.Foundation.DI.Extensions{
public static class ServiceCollectionExtensions
{
    public static void AddMvcControllers(this IServiceCollection serviceCollection, params string[] assemblyFilters)
    {
        var assemblies = GetAssemblies.GetByFilter(assemblyFilters);

        AddMvcControllers(serviceCollection, assemblies);
    }

    public static void AddMvcControllers(this IServiceCollection serviceCollection, params Assembly[] assemblies)
    {
        var controllers = GetTypes.GetTypesImplementing<IController>(assemblies)
            .Where(controller => controller.Name.EndsWith("Controller", StringComparison.Ordinal));

        foreach (var controller in controllers)
            serviceCollection.AddTransient(controller);

        controllers = GetTypes.GetTypesImplementing<ApiController>(assemblies)
            .Where(controller => controller.Name.EndsWith("Controller", StringComparison.Ordinal));

        foreach (var controller in controllers)
            serviceCollection.AddTransient(controller);
    }
}}
public static class GetAssemblies
{
    public static Assembly[] GetByFilter(params string[] assemblyFilters)
    {
        var assemblyNames = new HashSet<string>(assemblyFilters.Where(filter => !filter.Contains('*')));
        var wildcardNames = assemblyFilters.Where(filter => filter.Contains('*')).ToArray();

        var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(assembly =>
            {
                var nameToMatch = assembly.GetName().Name;
                if (assemblyNames.Contains(nameToMatch)) return true;

                return wildcardNames.Any(wildcard => IsWildcardMatch(nameToMatch, wildcard));
            })
            .ToArray();

        return assemblies;
    }

    /// <summary>
    ///     Checks if a string matches a wildcard argument (using regex)
    /// </summary>
    private static bool IsWildcardMatch(string input, string wildcards)
    {
        return Regex.IsMatch(input, "^" + Regex.Escape(wildcards).Replace("\\*", ".*").Replace("\\?", ".") + "$",
            RegexOptions.IgnoreCase);
    }
}public static class GetTypes    {
    public static Type[] GetTypesImplementing<T>(params Assembly[] assemblies)
    {
        if (assemblies == null || assemblies.Length == 0)
            return new Type[0];

        var targetType = typeof(T);

        return assemblies
            .Where(assembly => !assembly.IsDynamic)
            .SelectMany(GetExportedTypes)
            .Where(type => !type.IsAbstract && !type.IsGenericTypeDefinition && targetType.IsAssignableFrom(type))
            .ToArray();
    }

    private static IEnumerable<Type> GetExportedTypes(Assembly assembly)
    {
        try
        {
            return assembly.GetExportedTypes();
        }
        catch (NotSupportedException)
        {
            // A type load exception would typically happen on an Anonymously Hosted DynamicMethods
            // Assembly and it would be safe to skip this exception.
            return Type.EmptyTypes;
        }
        catch (ReflectionTypeLoadException ex)
        {
            // Return the types that could be loaded. Types can contain null values.
            return ex.Types.Where(type => type != null);
        }
        catch (Exception ex)
        {
            // Throw a more descriptive message containing the name of the assembly.
            throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                "Unable to load types from assembly {0}. {1}", assembly.FullName, ex.Message), ex);
        }
    }
}

As I am using Glass Mapper so I want to use ISitecoreContext, for that I have register ISitecoreContext in Foundation/ORM for that I have performed these actions: 1. Created patch file inside Foundation/ORM

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"><sitecore><services>
<configurator type="Habitat.Foundation.ORM.DI.RegisterContainer, Habitat.Foundation.ORM" />
</services>  </sitecore>

public class RegisterContainer : IServicesConfigurator { public void Configure(IServiceCollection serviceCollection) { serviceCollection.AddTransient<ISitecoreContext, SitecoreContext>(); } }

Accesssing in controller like this

private readonly ISitecoreContext _sitecoreContext;

    public TestController(ISitecoreContext sitecoreContext)
    {
        _sitecoreContext = sitecoreContext;

    }

I accessing in two classes one way is _sitecoreContext.GetItem(Context.Site.ContentStartPath) and another way is _sitecoreContext.GetRootItem() then it started throwing error “{"Service has been disposed, cannot create object"}” in _sitecoreContext.GetItem(Context.Site.ContentStartPath) but working for _sitecoreContext.GetRootItem()

When I update AddTransient to AddSingleton then it works for some time for both but for after some time it started giving me null value of _sitecoreContext.

Please help me.

Swati Gupta
  • 753
  • 2
  • 8
  • 30
  • For anyone looking for answer check this blog - https://www.coreysmith.co/glass-mapper-5-dependency-injection/ – Harsh Baid Jul 06 '21 at 19:44

0 Answers0