2

我正在使用带有 Helix 框架的 Sitecore 8.2 Update 4,还使用了 Microsoft 扩展依赖注入。我为 DI 执行了几个步骤: 1. 在 Foundation 层创建了 DI 项目。2. 我在 App_config/Include/zFoundation 中创建了名为 Habitat.Foundation.DI.RegisterControllers 的管道

<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);
        }
    }
}

因为我使用的是 Glass Mapper,所以我想使用 ISitecoreContext,为此我在 Foundation/ORM 中注册了 ISitecoreContext,因为我已经执行了以下操作: 1. 在 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>(); } }

像这样访问控制器

private readonly ISitecoreContext _sitecoreContext;

    public TestController(ISitecoreContext sitecoreContext)
    {
        _sitecoreContext = sitecoreContext;

    }

我在两个类中访问一种方式是 _sitecoreContext.GetItem(Context.Site.ContentStartPath),另一种方式是 _sitecoreContext.GetRootItem() 然后它开始在 _sitecoreContext.GetItem 中抛出错误“{“服务已被处置,无法创建对象”} (Context.Site.ContentStartPath) 但为 _sitecoreContext.GetRootItem() 工作

当我将 AddTransient 更新为 AddSingleton 时,它对两者都工作了一段时间,但一段时间后它开始给我 _sitecoreContext 的空值。

请帮我。

4

0 回答 0