DryIoc - specifying dependency when using constructor injection - dryioc

Using DryIoc if I register two implementations of the same contract - how can control which implementation to use when using constructor injection?
I see you can you register with a key or metadata - is it possible (using an attribute?) to control with implementation is injected? Or should I require a collection and figure out the correct implementation in the ctor?

You can specify what dependency to consume in constructor via Made.Of strongly-typed spec, like so:
container.Register<SomeClient>(Made.Of(
() => new SomeClient(Arg.Of<IDep>("service key of impl")));
Here is the related SO answer with more options.
Attributed registration is supported via MEF Attributed Model:
[Export]
public class SomeClient {
public SomeClient([Import("x")]IDep dep) {}
}
[Export("x", typeof(IDep))]
public class X : IDep {}
[Export("y", typeof(IDep))]
public class Y : IDep {}
// in composition root:
using DryIoc.MefAttributedModel;
container = new Container().WithMefAttributedModel();
container.RegisterExports(
typeof(SomeClient),
typeof(X),
typeof(Y));
container.Resolve<SomeClient>(); // will inject X

Related

Adapter pattern : Why would we need to subclass the Adaptee?

For an Object Adapter design, GoF states :
makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself
My question is that why is this subclassing required when we are creating the clases as follows :
class Target {
public :
virtual void op() = 0 ;
} ;
class Adaptee {
public :
void adapteeOp() {cout<<"adaptee op\n" ;}
} ;
class Adapter : public Target {
Adaptee *adaptee ;
public :
Adapter(Adaptee *a) : adaptee(a) {}
void op() {
// added behavior
cout<<"added behavior\n" ;
adaptee->adapteeOp() ;
// more added behavior
cout<<"more added behavior\n" ;
}
} ;
main() { //client
Adapter adapter(new Adaptee) ;
adapter.op() ;
}
I have not been able to appreciate the requirement for subclassing as mentioned by GoF when I am able to override the behavior here also.
Please explain what is the point that I am missing out.
I have not been able to appreciate the requirement for subclassing as mentioned by GoF when I am able to override the behavior here also.
I see your confusion. Your example is too simple as it only contains cout statements. I wouldn't qualify adding cout statements before and after a call to one of Adaptees methods as adding any significant behavior. You need to consider more complex scenarios.
Imagine that you want to add newFunctionality to the Adaptee that uses the protected data from Adaptee. You can't modify the Adaptee so the only option you have is to subclass it.
class NewAdaptee : public Adaptee {
public :
void adapteeOp() {
cout<<"adaptee op\n" ; //step 3
}
void newFunctionality() { //use protected members from Adaptee }
} ;
The above code demonstrates a more complex use case of adding functionality to the Adaptee where subclassing is the only way to achieve this. So you now want to start using this new Adaptee in your Adapter. If you go with the object adapter option, you will need to start using a NewAdaptee reference in the Adaptor
class Adapter : public Target {
NewAdaptee *adaptee ;
//more code follows
}
This has the immediate issue that your Adapter can no longer be passed any direct subclasses of Adaptee. This is what they mean when they say It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself. This would take away the advantage of the object adapter approach which was to allow a single adapter to work with all the subclasses of the Adaptee.
Note : In the class adapter approach, NewAdaptee would actually be your adapter and would also inherit Target.

Open Generics Registration

Suppose I have the following classes:
public class Setup { }
public class Configuration<T> where T : class
{
internal Configuration(Setup setup) { }
}
public class Process<T> where T : class
{
internal Process(Configuration<T> configuration) { }
}
I want to register these classes in DryIoc and need each Process<T> to be singleton (as would be Configuration<T>). So, Process<ClassA> would resolve the same instance, and Process<ClassB> will do the same. But Process<ClassA> and Process<ClassB> would be 2 different instances.The same applies to Configuration<T>.How would I register these 3 classes to achieve what I need?Note that constructors are internal.
This is what I've done without success:
var container = new Container();
container.Register<Setup>(Reuse.Singleton);
container.Register(typeof (Configuration<>),
made: Made.Of(typeof (Configuration<>).GetConstructorOrNull(true, typeof (Setup))));
container.Register(typeof(Process<>), Reuse.Singleton,
Made.Of(typeof(Process<>).GetConstructorOrNull(true, typeof(Configuration<>))));
I get: "An exception of type 'System.NullReferenceException' occurred in DryIoc.dll but was not handled in user code" when, as an example I dovar a = container.Resolve<Process<EventArgs>>();
The problem is with getting constructor from generic type. For now you may use DryIoc API to get ConstructorWithResolvableArgumentsIncludingNonPublic:
Working sample looks like that:
var container = new Container();
container.Register<Setup>(Reuse.Singleton);
container.Register(typeof(Configuration<>), Reuse.Singleton,
made: FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublic);
container.Register(typeof(Process<>), Reuse.Singleton,
FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublic);
var p = container.Resolve<Process<EventArgs>>();
In future versions it will be more simple like FactoryMethod.Constructor(includeNonPublic: true).
Update with workaround:
This is an actual issue in DryIoc 2.9.7 with creating singletons with internal constructor. The fix is on the way. For now you can use a workaround by disabling certain singleton optimizations with rule:
var container = new Container(rules => rules.WithoutEagerCachingSingletonForFasterAccess());
Updated live sample.
Update with fix:
The problem is fixed in DryIoc 2.10

Class encapsulation: how to prepare code for adding new classes?

I have the following code:
class FooType1 : public FooInterface, public BarInterface1 {}
class FooType2 : public FooInterface, public BarInterface2 {}
class FooType3 : public FooInterface, public BarInterface3 {}
FooInterface service1 = boost::shared_ptr<FooType1>(new FooType1());
FooInterface service2 = boost::shared_ptr<FooType2>(new FooType2());
FooInterface service3 = boost::shared_ptr<FooType3>(new FooType3());
new Host(service1, service2, service3);
Host::Host(boost::shared_ptr<BarInterface1> service1,
boost::shared_ptr<BarInterface2> service2,
boost::shared_ptr<BarInterface3> service3) {
obj1 = service1;
obj2 = service2;
obj3 = service3;
}
I need to add FooType4, FooType5, etc. in a way analogoues to FooType1 through FooType3. In the Host constructor I have to assign the proper service to the proper object (1 to 1, 2 to 2, etc.). Given that I know there will be many new services added, how can I properly encapsulate this?
I thought about vector, because in a few places I have to perform some actions on all services so a "for each" loop will be helpful. How I can get the objects from a vector for the Host constructor in a reasonable way? Maybe some design pattern?
You said,
I need to add FooType4,FooType5, etc. in a way analogoues toFooType1throughFooType3. In theHost` constructor I have to assign the proper service to the proper object (1 to 1, 2 to 2, etc.). Given that I know there will be many new services added, how can I properly encapsulate this?
Given that, your approach is not the right one. If you haven't read the Open/Closed Prinicple, I strongly recommend reading it.
A better approach might be to allow services to be added to a Host by clients. This is what I am thinking.
class Host
{
public:
void addService(std::shared_ptr<FooInterface> service)
{
services_.push_back(service);
}
private:
std::vector<std::shared_ptr<FooInterface>> service_;
};
And use it as:
Host* host = new Host(service1, service2, service3);
host->addService(std::shared_ptr<FooInterface>(new FooType1()));
host->addService(std::shared_ptr<FooInterface>(new FooType2()));
host->addService(std::shared_ptr<FooInterface>(new FooType3()));

How to test using interface collection with Rhino.Mocks

In my interface
public IMyListInterface : IList<IMyItem>
{
void Foo();
}
how can I easily create an example for testing classes that use IMyListInterface.
Currently I'm using GenerateStub<MyListInterface>() and delegating the needed methods / properties to a List<IMyItem> list but it's tedious.
Currently to get the following code under test to work
foreach (var match in matchList)
I'm doing the following in my test class
IList<IMyItem> baseList = new List<IMyItem>();
IMyListInterface matchList = MockRepository.GenerateStub<IMyListInterface>();
matchList.Stub(m => m.GetEnumerator()).Return(null).WhenCalled(i => i.ReturnValue = baseList.GetEnumerator());
Is there a better way?
Implement the interface in an abstract base class for testing:
public abstract MyMockableList : List<MyItem>, IMyListInterface
{
public abstract void Foo();
}
You can then use MockRepository.GenerateStub<MyMockableList>(), which will function as a normal list (RhinoMocks won't override the methods inherited from List<MyItem>) but you can still stub out the Foo() method.

How to mock HttpClientCertificate?

I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.
code:
//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });
This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.
Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.
//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio
public class HttpClientCertificate : NameValueCollection {
public byte[] BinaryIssuer { get; }
public int CertEncoding { get; }
//other methods
//...
}
public class HttpClientCertificateBase {
private HttpClientCertificate m_cert;
public HttpClientCertificateBase(HttpClientCertificate cert) {
m_cert = cert;
}
public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
//other methods
//...
}
public class TestClass {
[TestMethod]
public void Test() {
//we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
var certMock = new Mock<HttpClientCertificate>(null);
certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
}
}
In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.
The issue is that you need to specify constructor parameters when creating the mock of the HttpClientCertificate.
var certMock = new Mock<HttpClientCertificate>(ctorArgument);
The bad news is that the ctor for HttpClientCertificate is internal and takes in an HttpContext, so it probably won't work.
Unless you want to write more code to make the class "Testable" I suggest you use Typemock Isolator, Unless specified otherwise it looks for the first c'tor available - public, internal or private and fake (mocks) it's parameters so you won't have to.
Creating the fake object is as simple as:
var fakeHttpClientCertificate = Isolate.Fake.Instance<HttpClientCertificate>();
Another alternative is to use the free Microsoft Moles framework. It will allow you to replace any .NET method with your own delegate. Check out the link as it gives an example that is pretty easy to understand. I think you'll find it much nicer than adding layers of indirection to get HttpClientCertificate into a testable state.