我正在使用带有 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 的空值。
请帮我。