Autofac Set Property to Instance
I'm fairly new to Autofac and I'm trying to set a public property on a class every time it is initialized. Here is the scenario. I have many classes that inherit from "Entity" that follow this basic format...
public class Person : Entity
{
public virtual DataContext ServiceContext { get; set; }
public string FirstName {get; set;}
...
}
These classes will typically be instantiated by a LINQ query like this:
var context = SomeContext(connection);
var people = context.Query<Person>().Where(item => item.FirstName == "Joe").ToList();
What I'm trying to accomplish is to pass in the "context" object into the ServiceContext property of the Person class each time it is instantiated. In this example, each Person in the people List would have this property set.
Ideally I would pass the DataContext in through a constructor of "Entity" but the problem is I don't have access to Entity or the Linq provider as they are from a third party. So my question is, using Autofac, ho开发者_开发技巧w do I inject a "context" into the "ServiceContext" property of every class that derives from "Entity"? It seems like the OnActivating event is close to what I need but I can't get it to work.
Autofac does allow you to inject properties on component activation. For your purposes, there are a couple of ways to do it.
First, you have to figure out how you want to construct the DataContext. You can register the construction of it in a lambda, you can register a specific instance, or you can register the type with parameters.
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));
Once you have that, you can register your types and set the properties to be autowired:
builder.RegisterType<Person>().PropertiesAutowired();
What that will do is after the Person object is created, any properties that can be set by Autofac will be. In this case, the DataContext will be resolved and set. Just make sure when you register your types deriving from "Entity" (and you do need to register all of them or Autofac won't have them in its component registry to resolve) that you add "PropertiesAutowired" at the end.
Something similar to what was posted earlier by @Chingiz:
builder.RegisterAssemblyTypes(typeof(Person).Assembly)
.Where(t => t.IsAssignableFrom(typeof(Entity)))
.PropertiesAutowired();
If you need more control over it, you may need to check out the Autofac wiki on property injection and component activation events for some ideas/reference.
Maybe this will help you
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)));
精彩评论