2011-02-02 4 views
3

Я довольно новичок в Autofac, и я пытаюсь установить публичное свойство в классе каждый раз, когда он инициализируется. Вот сценарий. У меня есть много классов, наследуемых от «лица», которые следуют этому основному формату ...Autofac Set Property to Instance

public class Person : Entity 
{ 
    public virtual DataContext ServiceContext { get; set; } 
    public string FirstName {get; set;} 
    ... 
} 

Этих классы, как правило, быть реализован с помощью запроса LINQ, как это:

var context = SomeContext(connection);  
var people = context.Query<Person>().Where(item => item.FirstName == "Joe").ToList(); 

То, что я пытаюсь для выполнения - передать объект «context» в свойство ServiceContext класса Person каждый раз при его создании. В этом примере каждое Person в списке людей будет иметь это свойство.

В идеале я бы передал DataContext через конструктор «Entity», но проблема в том, что у меня нет доступа к Entity или Linq-провайдеру, поскольку они принадлежат третьей стороне. Итак, мой вопрос заключается в использовании Autofac, как мне добавить «контекст» в свойство «ServiceContext» для каждого класса, который происходит от «Entity»? Похоже, что событие OnActivating близко к тому, что мне нужно, но я не могу заставить его работать.

ответ

0

Может быть, это поможет вам

public class Person : Entity 
{ 
    public Person(DataContext context) 
    { 
     ServiceContext = context; 
    } 
    public virtual DataContext ServiceContext { get; set; } 
    public string FirstName { get; set; } 
} 

builder.Register<DataContext>(c => new DataContext(connectionString)).InstancePerHttpRequest(); 
builder.RegisterAssemblyTypes(typeof (Person).Assembly) 
    .Where(t => t.IsAssignableFrom(typeof (Entity))); 
+0

Это не работает. Строка: builder.Register () дает ошибку компиляции, и я не вижу, где вы устанавливаете DataContext для объекта контекста? Я попробовал пару других вещей, таких как builder.RegisterInstance (контекст). Как () безрезультатно. –

+0

Поскольку DataContext нуждается в строке подключения. исправлено. –

+0

Я не думаю, что это сработает, потому что сторонний поставщик Linq, похоже, использует конструктор без параметров. Есть ли способ сделать это путем введения свойств во время активации? –

9

Autofac действительно позволяет Вам вводить свойства на активацию компонентов. Для ваших целей есть несколько способов сделать это.

Во-первых, вам нужно выяснить, как вы хотите построить DataContext. Вы можете зарегистрировать его конструкцию в лямбда, вы можете зарегистрировать конкретный экземпляр или зарегистрировать тип с параметрами.

var builder = new ContainerBuilder(); 

// You can register an instance... 
var context = new DataContext(connectionString); 
builder.RegisterInstance(context).As<DataContext>(); 

// OR you can register construction in a lambda... 
builder.Register(c => new DataContext(connectionString)).As<DataContext>(); 

// OR you can register the type with constructor parameters. 
builder.RegisterType<DataContext>() 
     .WithParameter(
      new NamedParameter("fileOrServerOrConnection", connectionString)); 

После того, как вы есть, что вы можете зарегистрировать типы и установить свойства быть autowired:

builder.RegisterType<Person>().PropertiesAutowired(); 

Что это будет делать это после того, как объект Person создается, все свойства, которые могут быть установлены by Autofac будет. В этом случае DataContext будет разрешен и установлен. Просто убедитесь, что когда вы регистрируете свои типы, происходящие из «Entity» (и вам необходимо зарегистрировать их все, или Autofac не будет иметь их в своем реестре компонентов, чтобы разрешить), которые вы добавляете «PropertiesAutowired» в конце.

Нечто похожее на то, что была опубликована ранее @Chingiz:

builder.RegisterAssemblyTypes(typeof(Person).Assembly) 
     .Where(t => t.IsAssignableFrom(typeof(Entity))) 
     .PropertiesAutowired(); 

Если вам нужно больше контроля над ним, возможно, потребуется проверить вики Autofac на property injection и component activation events некоторые идеи/ссылки.