Я столкнулся с проблемой картирования. Мое решение, как показано ниже.
У меня есть два проекта
1. Azure Function (v1) project with Framework: .Net Framework 4.7.2
2. Class Library with Framework: .Net Framework 4.7.2
В 1-м проекте у меня есть функция Azure, которая запускается с использованием очереди и вызывает мою функцию BeginBackup (токен CancellationToken, DateTime.Now ()), которые существуют в моем конкретном классе.
Я вызываю свою функцию, как показано ниже, из функции Azure.
DependencyContext.Instance.Locator.GetInstance<IBackupTableStorageService>().BeginBackup(cancellationToken, SystemTime.UtcNow());
Мой класс DependencyContext.cs находится ниже.
using ClassLibrary1.BackupTableStorage;
using CommonServiceLocator;
using StructureMap;
using System;
using System.Collections.Generic;
namespace AzureFunctionsProject.Functions
{
public interface IDependencyContext
{
IServiceLocator Locator { get; }
}
public class DependencyContext : IDependencyContext
{
private static volatile IDependencyContext _instance;
private static readonly object SyncRoot = new Object();
public static IDependencyContext Instance
{
get
{
if (_instance == null)
{
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new DependencyContext();
}
}
}
return _instance;
}
set => _instance = value;
}
public IServiceLocator Locator { get; private set; }
public DependencyContext()
{
Build();
}
private void Build()
{
var registry = new Registry();//Registry is the class belongs to StructureMap.
var container = new Container();
var serviceLocatorProvider = new StructureMapServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocatorProvider);
Locator = serviceLocatorProvider;
// register the container itself
registry.For<IServiceLocator>().Use(ServiceLocator.Current);
// Apply the registry to the container
container.Configure(x =>
{
x.AddRegistry<Domain.Registry>();
x.AddRegistry(registry);
});
}
}
public class StructureMapServiceLocator : ServiceLocatorImplBase
{
private IContainer Container { get; set; }
public StructureMapServiceLocator(IContainer container)
{
Container = container;
}
protected override object DoGetInstance(Type serviceType, string key)
{
if (string.IsNullOrEmpty(key))
{
return Container.GetInstance(serviceType);
}
return Container.GetInstance(serviceType, key);
}
protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
{
foreach (object obj in Container.GetAllInstances(serviceType))
{
yield return obj;
}
}
}
}
У меня есть другой класс Registery, который я создал и который отображает мой интерфейс на мой конкретный класс.
Файл Registery.cs находится ниже.
namespace ClassLibrary1.Domain
{
public class Registry: StructureMap.Registry
{
public Registry()
{
// The Localization Service needs to be passed a function to record exceptions
For<ILocalizationService>().Use<LocalizationService>()
.Ctor<LocalizationService.LogException>().Is(context => CreateExceptionLogger(context));
For<ICloudStorageWrapper>().Use<CloudStorageWrapper>();
For<IBackupTableStorageService>().Use<BackupTableStorageService>();
}
private LocalizationService.LogException CreateExceptionLogger(IContext context)
{
return (ex, c, m) =>
{
var logger = context.GetInstance<ILogicalOperationsLogger>();
logger.ErrorException(m, ex);
};
}
}
}
Как и у меня, у меня есть мой интерфейс и уважаемый для создания класса, который имеет определение моего метода BeginBackup (токен CancellationToken, DateTime.Now ());
Я получаю исключение в методе DoGetInstance в классе DependencyContext.cs.
Я новичок в IoC и внедрении зависимостей, пожалуйста, дайте мне знать, что я делаю неправильно, если что-то требуется, чтобы прояснить вопрос, пожалуйста, дайте мне знать.