Произошла ошибка активации при попытке получить экземпляр типа IBackupTableStorageService, ключ "" Библиотека StructureMap - PullRequest
1 голос
/ 06 марта 2019

Я столкнулся с проблемой картирования. Мое решение, как показано ниже.

У меня есть два проекта

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 и внедрении зависимостей, пожалуйста, дайте мне знать, что я делаю неправильно, если что-то требуется, чтобы прояснить вопрос, пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 18 марта 2019

Попробуйте переместить регистрацию для IServiceLocator в действие настройки.Вы также можете удалить созданный вами объект Registry:

   private void Build()
   {
       var container = new Container();

       var serviceLocatorProvider = new StructureMapServiceLocator(container);
       ServiceLocator.SetLocatorProvider(() => serviceLocatorProvider);
       Locator = serviceLocatorProvider;

       // Apply the registry to the container
       container.Configure(x =>
       {
           // register the container itself
           x.For<IServiceLocator>().Use(serviceLocatorProvider);
           x.AddRegistry<Domain.Registry>();
       });
   }
...