2016-08-17 2 views
1

У нас есть проект ASP.NET, и мы используем AutoFac для DI. У нас есть уровень сервиса со всеми запросами базы данных, и нам нужно сделать некоторые запросы в статическом классе.AutoFac DI в статическом классе

Это, как мы регистрируем зависимости в Global.asax:

public class Dependencies 
{ 
    public static void RegisterDependencies() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired(); 

     builder.RegisterModule(new ServiceModule()); 
     builder.RegisterModule(new EfModule()); 

     var container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
    } 
} 

public class ServiceModule : Autofac.Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterAssemblyTypes(Assembly.Load("MyApp.Service")).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope(); 
    } 

} 

public class EfModule : Autofac.Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType(typeof(myDataContext)).As(typeof(IMyContext)).InstancePerLifetimeScope(); 
    } 
} 

И это, как мы получаем доступ в контроллере:

public class SomeController : Controller 
{ 
    private readonly IService1 _service1; 
    private readonly IService2 _service2; 

    public SomeController(IService1 service1, IService2 service2) 
    { 
     _service1 = service1; 
     _service2 = service2; 
    } 


    public ActionResult Index() 
    { 
     var service = _service1.GetAll(); 
     ... 

     return View(searchModel); 
    } 
} 

Теперь нам нужно извлечь данные из базы данных в статическом классе, поэтому нам нужно называть наш сервисный уровень, но мы не знаем, как это сделать ... мы это видели, но я не знаю, правильно ли это, но он работает.

public static Test() 
{ 
    ... 
    var service1 = DependencyResolver.Current.GetService<IService1>(); 
    ... 
} 

Также, как это было бы в нестатических и статических классах?

Заранее спасибо.

+2

Вы не можете (и не должны) вводить в статический класс. Подумайте, что произойдет, когда одновременно появятся 2 веб-запроса и попытайтесь получить доступ к одному и тому же объекту контекста. Вместо этого, почему бы не пройти службу в качестве параметра? – DavidG

+0

Хорошо, что если класс не является статичным? Как я могу это сделать? Я хочу, чтобы я мог вызвать метод внутри класса, не зная, что происходит внутри, поэтому, поскольку мне нужно получить информацию из базы данных, мне нужно вызвать услугу (или несколько), но я не хочу беспокоиться об этих услуги за пределами класса ... так как я хочу просто позвонить и получить информацию. –

+0

Где ваш статический класс находится в жизненном цикле запроса? Если это называется где-то в вашем «Контроллере», сделайте то, что сказал вам DavidG: объявите функцию «public static Test (IService1 service1)» и перейдите в 'service1' из вашего' Controller'. –

ответ

3

Проблема заключается в том, что я должен назвать многие из этих классов из разных мест, и я не хочу зависеть от службы, чтобы назвать класс, я бы хотел, чтобы класс заботился обо всем ,

В этом случае вы должны зарегистрировать свой класс с Autofac так, что он получает его зависимости впрыскивается:

builder.RegisterType<MyClass>(); 

Если класс используется несколько раз в течение одного запроса может быть полезно, чтобы зарегистрировать его с помощью InstancePerLifetimeScope(), но это зависит от вашей общей архитектуры. См. Это link в документации Autofac для получения дополнительной информации.

Конечно, вы должны изменить свой класс, так что методы не являются статичными больше и добавить конструктор, чтобы получить зависимости:

public class MyClass 
{ 
    private readonly IService1 _service1; 

    public MyClass(IService1 service1) 
    { 
     _service1 = service1; 
    } 

    public void Test 
    { 
     // use the _service1 instance to do whatever you want 
    } 
} 

Теперь вы можете вводить MyClass зависимость в контроллере и использовать его без необходимости знать что-либо о его внутренних компонентах или его зависимостях:

public class SomeController : Controller 
{ 
    private readonly IService1 _service1; 
    private readonly IService2 _service2; 

    private readonly MyClass _myClass; 

    public SomeController(IService1 service1, IService2 service2, MyClass myClass) 
    { 
     _service1 = service1; 
     _service2 = service2; 
     _myClass = myClass; 
    } 


    public ActionResult Index() 
    { 
     var service = _service1.GetAll(); 
     ... 

     _myClass.Test(); 

     return View(searchModel); 
    } 
} 
+0

Отличное решение, но я пробовал это решение, и мне не нужно регистрировать мой класс с помощью AutoFac, остальное я сделал то же самое. Благодарю. –

Смежные вопросы