2014-09-25 4 views
1

фона:Как передать значение времени выполнения параметру конструктора при регистрации типа?

У меня есть много классов по имени XxxService, где один из параметров конструктора является UserId, как

public XxxService: IXxxService 
{ 
    public XxxService(string userId, IMmmService mmm, INnnService nnn) {....} 
} 

идента исходит от HttpContext.Current.Request.Cookies. Число классов обслуживания огромно, поэтому я не хочу создавать интерфейс IIdProvider для каждого класса обслуживания.

Я знаю, что при регистрации могу передать значение времени компиляции конструктору.

container.RegisterType<IService, Service> 
    (new InjectionConstructor(5,      //<-- compile time value 
      container.Resolve<IMmmService>(), 
      container.Resolve<INnnService>())); 

Как передать функцию конструктору? Что-то вроде:

container.RegisterType<IService, Service> 
    (new InjectionConstructor(()=>GetIdFromRequest(), //<--- runtime value 
      container.Resolve<IMmmService>(), 
      container.Resolve<INnnService>())) 

Я также знаю, что есть InjectionFactory

container.RegisterType<IService, Service> 
    (new InjectionFactory( 
      (x)=> new Service( 
      GetIdFromRequest(), 
      container.Resolve<IMmmService>(), 
      container.Resolve<INnnService>())) 

Но это нужно решать другие параметры вручную.

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

Так самое, что я хочу что-то вроде:

// fake code 
container.RegisterType<IService, Service> 
    (new InjectedParameter(0,  // the first parameter 
      ()=>GetIdFromRequest() // <--- runtime value 
      ) 

ответ

3

В методе InjectionFactory используйте перегружать Resolve метод, который позволяет определить ResolverOverride, конкретно ParameterOverride и передать значение времени выполнения таким образом. Чтобы избежать StackOverflowException, вы можете использовать дополнительные именованные регистрации со значениями времени компиляции, предусмотренные для соответствующих параметров, как это:

class A 
{ 
    public A(int id, B b, C c) 
    { 
     Trace.WriteLine("Got " + id); 
    } 
} 

class B { } 

class C { } 

static void Main(string[] args) 
{ 
    using (var unity = new UnityContainer()) 
    { 
     unity.RegisterType<A>(
      "compile-time", 
      new InjectionConstructor(-1, 
       new ResolvedParameter<B>(), 
       new ResolvedParameter<C>() 
       ) 
     ); 
     unity.RegisterType<A>(
      new InjectionFactory(
      u => u.Resolve<A>("compile-time", 
       new ParameterOverride("id", new Random().Next())) 
      ) 
     ); 
     unity.Resolve<A>(); 
     unity.Resolve<A>(); 
     unity.Resolve<A>(); 
    } 
} 
+0

Можете ли вы показать код, пожалуйста? – Zach

+0

Вы правы, ведь это не так очевидно. Я добавлю полный пример. – cynic

+0

container.RegisterType (новый InjectionFactory (c => c.Resolve (новый параметр ParameterOverride («Userd», GetIdFromRequest())))); выдает исключение StackoverflowException. – Zach

0

Я не вижу никакой фактической проблемы с InjectionFactory подхода.

Но вся концепция службы, которая хранит имя пользователя как часть его состояния, кажется мне неправильной.

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

public interface IAuthenticationService 
{ 
    string GetCurrentUserName(); 
} 

public class CookieBasedAuthenticationService : IAuthenticationService 
{ 
/// ... 
} 

Вы можете полностью удалить часть кода конфигурации с помощью InjectionConstructor.

+0

Не уверен, что если вы видели мой обновленный пост. Значение 1 должно быть значением времени выполнения. Является ли это возможным? – Zach

+0

извините, я не понял вопрос полностью с первого раза –

+0

Большое спасибо. Однако параметр «UserId» используется почти во всех классах обслуживания (огромное количество). Я не хочу их менять. – Zach

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