Resolve externally created object instance with no public constructor - inversion-of-control

Using the adapter pattern, combined with IoC (specificly Unity), I would like to create a new instance of a object of which the properties point back to the adaptee's propeties (basicly mapping the adaptee to a target object).
As a example I have the following class structures:
public class Adaptee
{
private Adaptee() { }
public int MyProperty { get; set; }
public static Adaptee New()
{
return new Adaptee();
}
}
public class Target
{
public int MyProperty { get; set; }
}
public class Adapter : Target
{
public Adapter(Adaptee adaptee)
{
this.MyProperty = adaptee.MyProperty;
}
}
public class MyTestClass
{
public Target MyTarget { get; set; }
}
The problem is that the Adaptee is not under my control and it has no public constructor, hence the use of the adapter. So Adaptee gets created as follow
Adaptee adaptee = Adaptee.New();
adaptee.MyProperty = 5;
In the actual code the above code would be executed in a externally controlled assembly and then passed to the following code:
using (UnityContainer container = new UnityContainer())
{
container
.RegisterType<MyTestClass>(
new InjectionProperty("MyTarget"));
container.RegisterInstance<Adaptee>(adaptee, new ExternallyControlledLifetimeManager());
MyTestClass myTestClass = container.Resolve<MyTestClass>();
}
I would like the execution of the code to result in the following:
Debug.Assert(myTestClass != null);
Debug.Assert(myTestClass.MyTarget != null);
Debug.Assert(myTestClass.MyTarget.MyProperty == adaptee.MyProperty);
This means that a resolved instance of Adapter should be injected into the MyTarget property of the myTestClass instance. The instance of Adapter should have been created with externally created instance of Adaptee.
The following code:
container
.RegisterType<MyTestClass>(
new InjectionProperty("MyTarget"));
should actually result in this:
container
.RegisterType<MyTestClass>(
new InjectionProperty("MyTarget", container.Resolve<Adapter>()));
This does not seem to be possible, since no instance of Adapter exist yet and it has a private constructor.
Should I use interception or something to achive this?

I was close with the container.Resolve<Adapter>() idea, but the final answer is simply to use the ResolvedParameter class when configuring the property to be injected using the InjectionProperty class:
new InjectionProperty(
"MyTarget",
new ResolvedParameter<Adapter>()));
So the calling code would look as follow:
Adaptee adaptee = Adaptee.New();
adaptee.MyProperty = 5;
using (UnityContainer container = new UnityContainer())
{
container
.RegisterType<MyTestClass>(
new InjectionProperty(
"MyTarget",
new ResolvedParameter<Adapter>()));
container.RegisterInstance<Adaptee>(adaptee, new ExternallyControlledLifetimeManager());
MyTestClass myTestClass = container.Resolve<MyTestClass>();
}
I found the solution in the following post:
Setter / property injection in Unity without attributes
Hope this helps someboby else.

That was a Doh! moment.
The solution is to add the following when configuring unity:
.RegisterType<Target, Adapter>()
I can't believe I missed that, such a simple solution which solves the problem (I think).
So te MyTarget property on the MyTestClass will resolve to a instance of the Adapter since it inherits from Target. The Adapter will obviously be initiated with the externally created instance of the Adaptee class.

Related

Autofac - InstancePerLifetimeScope vs InstancePerRequest in Application_Start in ASP.NET Web Forms

I am using Autofac With ASP.NET Webforms. I would like to understand the difference between InstancePerLifetimeScope and InstancePerRequest when i register dependencies in the App_Start method of the global.asx.
It look like that for both of them a new instance of the dependency is created just once at Every HttpRequest (verified with a breakpoint into the constructor of the dependency and with the HashCode of the object).
Any ideas?
Thank you
#Travis gave good link to the documentation describing how it works. However, I prefer to give examples additionally to illustrate the theory better. So, let's take a look at simple example.
Suppose you have two classes ClassA and ClassB implementing some simple interfaces IClassA and IClassB.
public class ClassA : IClassA
{
public ClassA() {
}
}
public class ClassB : IClassB
{
public ClassB() {
}
}
Now, let's see what happens when we register them in different ways.
Example A
builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().As<IClassB>().InstancePerLifetimeScope();
Then, in the controller, you do this:
public class HomeController : Controller
{
private readonly IClassA _classA;
private readonly IClassB _classB;
private readonly IComponentContext _ctx;
public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
_classA = classA;
_classB = classB;
_ctx = ctx;
}
public string Get() {
using (var scope = _ctx.BeginLifetimeScope()) {
var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == false
return "Ok";
}
}
}
In this example both 'new' variables in Get() method will receive new instances since they are both registered to be unique per lifetime scope. We began new lifetime scope - we got new instances.
Now, let's take a look at another example.
Example B
builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().As<IClassB>().InstancePerRequest(); // now they have different life time!
// controller:
public class HomeController : Controller
{
private readonly IClassA _classA;
private readonly IClassB _classB;
private readonly IComponentContext _ctx;
public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
_classA = classA;
_classB = classB;
_ctx = ctx;
}
public string Get() {
using (var scope = _ctx.BeginLifetimeScope()) {
var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == true
return "Ok";
}
}
}
See what happened here? Even though we began new lifetime scope - ClassB still gets resolved from request scope and not from our new one. This is the difference between InstancePerLifetimeScope() and InstancePerRequest().
And as documentation suggests, internally it is based on another Autofac concept - InstancePerMatchingLifetimeScope().
In many cases it amounts to the same thing. This is an FAQ on the Autofac doc site.

How do I combine a Controlled Lifetime relationship type (i.e. Owned<T>) with a delegate factory?

In my application, I have a service that requires a constructor parameter not resolved by Autofac, that I instantiate using a delegate factory:
public class Service
{
public Service(string parameter /*, ... other dependencies */)
{
}
public delegate Service Factory(string parameter);
}
This works great! I really love this feature.
I also like the Controlled Lifetime relationship, so I can let my component depend on a Func<Owned<ISomething>> like this:
public class Component
{
private Func<Owned<ISomething>> _somethingFactory;
/* constructor omitted for brevity */
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory())
{
/* Lots of useful code here */
}
}
}
My problem is that now I want to combine the two. I can't have an instance of Func<Owned<Service>> injected, because it needs that parameter, so my current solution is to abstract the factory away into another service, say IServiceFactory:
public interface IServiceFactory
{
Service Create(string parameter);
}
...implemented as such:
public class ServiceFactory : IServiceFactory
{
private Service.Factory _internalFactory;
public ServiceFactory(Service.Factory internalFactory)
{
_internalFactory = internalFactory;
}
public Service Create(string parameter)
{
return _internalFactory(parameter);
}
}
My component then becomes this:
public class Component
{
Func<Owned<IServiceFactory>> _serviceFactoryFactory;
/* ... */
}
The need for such a field name leaves a bad taste in my mouth to the point that I suspect there must be a cleaner way to handle this case.
Is there another way?
You could change your injected factory to include the string parameter:
private Func<string, Owned<ISomething>> _somethingFactory;
Then you can pass the string to the factory when you want to create a new instance:
public void DoSomethingUseful()
{
using (var ownedSomething = _somethingFactory("my parameter"))
{
/* Lots of useful code here */
}
}
I've created a .NET Fiddle with a small working sample.

Shim DbContext ctor for Effort unit testing

I'd like to intercept var context = new MyDbContext() to return a different constructor call instead.
The great thing about EFfort is that it let's you set up an easy in-memory database for unit testing.
var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);
But then you'd have to inject that context into your repository.
public FooRepository(MyDbContext context) { _context = context; }
Is it possible to just intercept var context = new MyDbContext() , so that it returns the testContext?
using (var context = new MyDbContext()) {
// this way, my code isn't polluted with a ctor just for testing
}
You have two possible options. Using factories or via Aspect oriented programming (like PostSharp)
referencing this article: http://www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx
Using PostSharp (AOP)
PostSharp is a great tool and can achieve the most clean interception
possible (meaning no changes in your classes and object generation at
all even if you do not your factories for object creation and/or
interfaces) but it is not a free library. Rather than creating proxies
at runtime, it injects code at compile time and therefore changes your
initial program in a seamless way to add method interception.
.....
The cool thing in this is that you do not change anything else in your
code, so your object can be still generated using the new keyword.
Using DI and Factory-pattern
I personally prefer the factory-pattern approach, but you seem apposed to having to inject any dependencies into your classes.
public interface IDbContextFactory<T> where T : DbContext {
T Create();
}
public class TestDbContextFactory : IDbContextFactory<MyDbContext> {
public MyDbContext Create() {
var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);
return testContext;
}
}
public class FooRepository {
MyDbContext _context;
public FooRepository(IDbContextFactory<MyDbContext> factory) {
_context = factory.Create();
}
}
(edit: I just realized this isn't actually returning the other ctor call. working on it.)
Figured it out. Simple enough if you know how to do it:
[TestMethod]
public void Should_have_a_name_like_this()
{
// Arrange
var connection = Effort.DbConnectionFactory.CreateTransient();
ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);
// Act
// Assert
}
And as usual, EFfort requires this constructor in the DbContext class:
public class SomeDbContext
{
public SomeDbContext() : base("name=Prod")
{
}
// EFfort unit testing ctor
public SomeDbContext(DbConnection connection) : base(connection, contextOwnsConnection: true) {
Database.SetInitializer<SolrDbContext>(null);
}
}
But it means the repo is blissfully unaware of the special Transient connection:
public class SomeRepository
{
public void SomeMethodName()
{
using (var context = new SomeDbContext())
{
// self-contained in repository, no special params
// and still calls the special test constructor
}
}
}

Autofac equivalent of "BuildUp"

Structuremap defines a 'BuildUp' method that takes an already-constructed object and performs setter injection to push in configured dependencies into that object.
Does Autofac have an equivalent method ?
The question was referring to already-constructed objects (ones not registered in the container) so the correct answer is either InjectProperties or InjectUnsetProperties.
The following test demonstrates the behaviour
public class TestPropertyInjection
{
public object ShouldBeInjectedByAutofac { get; set; }
}
[Fact]
public void Autofac_can_inject_properties()
{
var builder = new ContainerBuilder();
builder.RegisterType(typeof(object));
var container = builder.Build();
var existingObjectNotRegisteredInContainer = new TestPropertyInjection();
container.InjectProperties(existingObjectNotRegisteredInContainer);
// can also use InjectUnsetProperties to only set unset properties
//container.InjectUnsetProperties(existingObjectNotRegisteredInContainer);
Assert.NotNull(existingObjectNotRegisteredInContainer.ShouldBeInjectedByAutofac);
}
Try InjectUnsetProperties.
Sample:
public class YourModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<YourClass>().OnActivated(e => e.Context.InjectUnsetProperties(e.Instance));
}
}
In more recent versions of Autofac you can simply use:
builder.RegisterType<YourClass>().PropertiesAutowired();

Getting TinyIoc current container in a Nancy project

I'm building a small Nancy web project.
In a method of one of my classes (not a nancy module), I would like to basically do:
var myThing = TinyIoC.TinyIoCContainer.Current.Resolve<IMyThing>();
However, there is only one registration in .Current (non public members, _RegisteredTypes) which is:
TinyIoC.TinyIoCContainer.TypeRegistration
Naturally, in my above code, I'm getting:
Unable to resolve type: My.Namespace.IMyThing
So, I guess I'm not getting the same container registered in my bootstrapper?
Is there a way to get at it?
EDIT
To flesh out a bit more of what I'm trying to do:
Basically, my url structure looks something like:
/{myType}/{myMethod}
So, the idea being, going to: /customer/ShowAllWithTheNameAlex would load the Customer service, and execute the showAllWithTheNameAlex method
How I do this is:
public interface IService
{
void DoSomething();
IEnumerable<string> GetSomeThings();
}
I then have an abstract base class, with a method GetService that returns the service.
It's here that i'm trying to use the TinyIoC.TinyIoCContainer.Current.Resolve();
In this case, it would be TinyIoC.TinyIoCContainer.Current.Resolve("typeName");
public abstract class Service : IService
{
abstract void DoSomething();
abstract IEnumerable<string> GetSomeThings();
public static IService GetService(string type)
{
//currently, i'm doing this with reflection....
}
}
Here's my implementation of the service.
public class CustomerService : Service
{
public void DoSomething()
{
//do stuff
}
public IEnumerable<string> GetSomeThings()
{
//return stuff
}
public IEnumerable<Customer> ShowAllWithTheNameAlex()
{
//return
}
}
Finally, I have my Nancy Module, that looks like:
public class MyModule : NancyModule
{
public MyModule()
{
Get["/{typeName}/{methodName}"] = p => ExecuteMethod(p.typeName, p.methodName);
}
private dynamic ExecuteMethod(string typeName, string methodName)
{
var service = Service.GetService(typeName);
var result = service.GetType().GetMethod(methodName).Invoke(service, null);
//do stuff
return result; //or whatever
}
}
#alexjamesbrown - The short answer is, you don't. Nancy was specifically designed so that you did not deal with the container directly. You mention that the class, that you want to take a dependency on IMyThing, is not a NancyModule. Well this is not an issue, as long as one of your modules has a reference to it, then those dependencies can also have their own dependencies that will be satisfied at runtime.
public interface IGreetingMessageService
{
string GetMessage();
}
public class GreetingMessageService: IGreetingMessageService
{
public string GetMessage()
{
return "Hi!";
}
}
public interface IGreeter
{
string Greet();
}
public class Greeter
{
private readonly IGreetingMessageService service;
public Greeter(IGreetingMessageService service)
{
this.service = service;
}
public string Greet()
{
return this.service.GetMessage();
}
}
public class GreetingsModule : NancyModule
{
public GreetingModule(IGreeter greeter)
{
Get["/"] = x => greeter.Greet();
}
}
The above will work just fine and Greeter will have it's dependency on IGreetingMessageService satisfied at runtime
I have had a very similar issue, needing to "share" the container. The reason this is an issue is that my program runs as a service using Nancy self hosting to provide a REST API. My modules have dependencies which are injected by Nancy itself, but the other parts of the app which are not referenced from modules also need dependencies injected.
Multiple containers are not a sensible option here (or anywhere really), I need to share the container between Nancy and the rest of the app.
I simply did the following
(I'm using Autofac but I suspect that TinyIoC in similar)
public class Bootstrapper : AutofacNancyBootstrapper
{
private static readonly Lazy<ILifetimeScope> container = new Lazy<ILifetimeScope>(RegisterTypes);
public static ILifetimeScope Container => container.Value;
protected override ILifetimeScope GetApplicationContainer()
{
return container.Value;
}
// Create container and register my types
private static ILifetimeScope RegisterTypes()
{
var builder = new ContainerBuilder();
// Register all my own types.....
return builder.Build();
}
}
Then, in my main code, I can use the container myself
public class Program
{
public static void Main(string[] args)
{
// Resolve main service with all its dependencies
var service = Bootstrapper.Container.Resolve<Service>();
service.Run();
}
}
As my NancyHost is within the Service, the container is constructed (once) upon its first use in main, this static is then used when Nancy gets round to creating the Bootstrapper itself.
In an ideal world, I wouldn't really want a globally accessible container, normally it would be local to the main function.
In this particular case "not dealing with the container directly" is highly problematic:
public interface IFoo {}
public class Foo : IFoo { public Foo(string bar) {} }
Assume IFoo already is a constructor dependency of a Nancy module.
Note the Foo constructor's string dependency. I need to communicate to the container to use that constructor for an IFoo singleton, when encountered as a Nancy module dependency. I need to register that on the TinyIoC instance NancyFx uses, and pass in the actual value of bar.