DryIoc call service method upon resolution - dryioc

How can I make DryIoc resolve Service as usual and immediately afterwards let it call its Adjust( int ) method with some specific parameters?
UPDATE: Based on suggestion provided by dadhi, the code is changed to use RegisterInitializer
public interface IMaster
{
void Run( int val );
}
public class Master : IMaster
{
public Master( IService service )
{
service_ = service;
}
public void Run( int val )
{
service_.Execute( val );
}
private readonly IService service_;
}
public interface IService
{
void Execute( int val );
}
public class Service : IService
{
public void Adjust( int state ) // This method does not belong to the interface
{
Console.WriteLine( "Service state is adjusted with {0}", state );
state_ = state;
}
public void Execute( int val )
{
var result = val + state_;
Console.WriteLine( "Service execution resulted in {0}", result );
}
private int state_;
}
static void Main( string[] args )
{
var container = new Container();
container.Register<Service>( Reuse.Singleton );
container.RegisterInitializer<IService>( ( service, resolver ) =>
{ // Casting type down is a bad idea.
( (Service)service ).Adjust( 5 );
} );
container.Register<IMaster, Master>( Reuse.Singleton,
Parameters.Of.Type<IService>( typeof( Service ) ) );
var master = container.Resolve<IMaster>();
master.Run( 10 );
}
The code above utilizes type cast which is, firstly, dirty enough to be blocked by our code quality standards.
Secondly, another registration may happen to map IService to AlternativeService, which has nothing to do with Adjust method.
So the question is why can I not replace container.RegisterInitializer<IService> with container.RegisterInitializer<Service>?
If I do this initialization code does not get called.
And more generally, is there any way to achieve what I want without explicit type casts? It would be great if we could link initialization to concrete classes rather than to interfaces.

You may need RegisterInitializer method.

Related

Resolution status in DryIoc container

Is it possible in DryIoc container to figure out whether some singleton has been instantiated?
For instance
var container = new Container();
container.Register<IApplicationContext, ApplicationContext>( Reuse.Singleton );
// var context = container.Resolve<IApplicationContext>();
if ( container.IsInstantiated<IApplicationContext>() ) // Apparently this does not compile
{
// ...
}
// OR
if ( container.IsInstantiated<ApplicationContext>() )
{
// ...
}
There is no way at the moment and no such feature planned. You may create an issue to request this.
But I am wandering why it is needed. Cause singleton provides a guarantee to be created only once, so you may not worry or check for double creation.
Is it for something else?
Update
OK, in DryIoc you may register a "decorator" to control and provide information about decoratee creation, here is more on decorators:
[TestFixture]
public class SO_IsInstantiatedViaDecorator
{
[Test]
public void Test()
{
var c = new Container();
c.Register<IService, X>(Reuse.Singleton);
c.Register<XProvider>(Reuse.Singleton);
c.Register<IService>(
Made.Of(_ => ServiceInfo.Of<XProvider>(), p => p.Create(Arg.Of<Func<IService>>())),
Reuse.Singleton,
Setup.Decorator);
c.Register<A>();
var x = c.Resolve<XProvider>();
Assert.IsFalse(x.IsCreated);
c.Resolve<A>();
Assert.IsTrue(x.IsCreated);
}
public interface IService { }
public class X : IService { }
public class A
{
public A(IService service) { }
}
public class XProvider
{
public bool IsCreated { get; private set; }
public IService Create(Func<IService> factory)
{
IsCreated = true;
return factory();
}
}
}
This example also illustrates how powerful is composition of DryIoc decorators and factory methods.

Open Generics with injected primitive

How can I register an Open Generic type with another open generic and primitive injected in the constructor?See example below.In this example, Resolve is throwing "Unable to resolve String as parameter "connectionString"" exception. (you can check live code here)
using System;
using DryIoc;
public class Program
{
public static void Main()
{
var container = new Container();
container.RegisterInstance("some_connection_string", serviceKey: "connectionString");
container.Register(typeof(Configuration<>), Reuse.Singleton);
container.Register(typeof (IEntityUpdater<>), typeof (SqlEntityUpdater<>), Reuse.Singleton);
var p = container.Resolve<IEntityUpdater<EventArgs>>();
Console.WriteLine(p);
}
}
public class Configuration<T> where T : class { }
internal interface IEntityUpdater<in T> where T : class
{
void Update(T entity);
}
internal class SqlEntityUpdater<T> : IEntityUpdater<T> where T : class
{
public SqlEntityUpdater(Configuration<T> configuration, string connectionString)
{
}
public void Update(T entity) { }
}
First, RegisterInstance is depricated, use UseInstance.
Second, the actual problem is that you registering instance with serviceKey and nowhere using this key for injection.
So, you either remove the serviceKey parameter.
Or, specify the key on injection side:
container.Register(typeof(IEntityUpdater<>), typeof(SqlEntityUpdater<>), Reuse.Singleton,
made: Parameters.Of.Type<string>(serviceKey: "connectionString"));

How to mock method with optional parameter in Google Mock?

How to mock a method with optional parameter in Google Mock?
For example:
class A
{
public:
void set_enable( bool enabled = true );
};
class MockA : public A
{
MOCK_METHOD1( set_enable, void( bool ) ); // this is not working
};
This is an alternative of Marko's answer: If you don't want to change your original code, just implement the helper in the mock class:
class A
{
public:
virtual void set_enable( bool enabled = true );
};
class MockA : public A
{
MOCK_METHOD1( set_enable_impl, void( bool ) );
virtual void set_enable( bool enabled = true )
{
set_enable_impl( enabled );
}
};
You still have to expect calls of set_enable_impl in your tests, for example
MockA mockA;
EXPECT_CALL(mockA, set_enable_impl(true)).Times(Exactly(1));
EXPECT_CALL(mockA, set_enable_impl(false)).Times(Exactly(1));
Change implementation of your method set_enable to use a helper method, like this:
void set_enable( bool enabled = true ) { set_enable_impl(enabled); }
Now, in class MockA, create a mock method for set_enable_impl:
MOCK_METHOD1( set_enable_impl, void( bool ) );
Then, in your production code you simply use set_enable as you would in the first place, while in tests you can set expectations on method set_enable_impl:
MockA mockA;
EXPECT_CALL(mockA, set_enable_impl(_))...;
An alternative would be to overload the method by having versions with one and zero parameters. It is up to you to determine which way works better for your case.
Some modifications to PiQuer's answer. You wouldn't need a wrapper if just add the name, "enabled" to the variable of type bool in your MOCK_METHOD1 like below:
class A
{
public:
void set_enable( bool enabled = true );
};
class MockA : public A
{
MOCK_METHOD1( set_enable, void( bool enabled ) );
};
Set two mocks like this:
class MockA : public A
{
MOCK_METHOD1( set_enable, void( bool ) );
MOCK_METHOD1( set_enable, void( ) );
};

How do I unit test a factory?

I unit test my classes by giving all my classes an interface. These interfaces have in turn their own mocks.
But lets say I have the following:
class IData
{
GetData()
}
class IOnScreenDataCalculator
{
Calculate(IData)
}
class OnScreenData : IOnScreenData
{
OnScreenData(PTR_T(IData), PTR_T(IOnScreenDataCalculator))
enter code here
GetOnScreenData()
}
Now lets say that I wish to have a number of factories for different types of data and calculators. How can I unit test these factories where my factories are as follows:
OnScreenBlueDataForWideScreenFactory
{
PTR:T(IOnScreenData) Create()
{
PTR_T(Data) data = ptr_t(new BlueData());
PTR_T(IOnScreenDataCalculator) calculator = ptr_t(new WideScreenDataCalculator());
PTR_T(IOnScreenData) onScreenData = ptr_t(new WideScreenDataCalculator(data, calculator ));
return onScreenData;
}
}
Thanks for your help,
Barry.
I am not sure the code snippets are really c++, but the example should be something like this :
class ExampleIface
{
public:
virtual ~ExampleIface() {}
virtual void a() = 0;
};
class Example1: public ExampleIface
{
public:
virtual ~Example1() {}
virtual void a()
{
// something
}
};
class ExampleFactory
{
public :
typedef ExampleIface * ExamplePtrType; // can be shared_ptr instead
static ExamplePtrType Create( /*params?*/)
{
ExamplePtrType p( new Example1 );
return p;
}
private:
ExampleFactory();
~ExampleFactory();
};
and the unit test:
void test_Create()
{
ExampleFactory::ExamplePtrType p = ExampleFactory::Create();
Example1 *realType = dynamic_cast< Example1* >( p );
TS_ASSERT( NULL != realType ); // if you use cxxtest
}
I'd call Create() and verify that I get a properly constructed object with the right constituent types.

Is this an acceptable way to test MVVM-Light Toolkit Messages?

[TestMethod()]
public void ShowSetup_SendsMessage_WhenShowSetupCommandCalled()
{
//Arrange
Messenger.Reset();
MainViewModel target = new MainViewModel();
bool wasCalled = false;
Messenger.Default.Register<NotificationMessage>(this,"Settings",(msg) => wasCalled = true);
//Act
target.ShowSetupCommand.Execute(null);
//Assert
Assert.IsTrue(wasCalled);
}
I see there is an IMessenger interface and I tried to mock it and set Messenger.OverrideDefault to the mock like this:
var mock = new Mock<IMessenger>();
Messenger.OverrideDefault((Messenger)mock.Object);
But I got an invalid cast error. Is the OverrideDefault method not for that purpose or more likely I'm using it incorrectly.
Or would I have an interface for the classes that are receiving the messages and mock those? All I really want to test is that a RelayCommand sends a message when it is called.
I just started to look at this myself. I'm a little surprised that Messenger.OverrideDefault doesn't take an IMessenger as a parameter. You have to inherit Messenger.
I suppose you could create a class that internally uses your mock object and then do a Verify.
[Test]
public void ShowSetup_SendsMessage_WhenShowSetupCommandCalled() {
Messenger.Reset();
MaintenanceViewModel target = new MainViewModel();
IMessenger mockMessenger = MockRepository.GenerateMock<IMessenger>();
mockMessenger.Expect(m => m.Send("Settings"));
TestMessenger testMessenger = new TestMessenger(mockMessenger);
Messenger.OverrideDefault(testMessenger);
bool wasCalled = false;
Messenger.Default.Register<NotificationMessage>(this, "Settings", (msg) => wasCalled = true);
target.ShowSetupCommand.Execute(null);
mockMessenger.VerifyAllExpectations();
}
You may or may not need a stub on the Register method.
The TestMessenger class:
public class TestMessenger : Messenger {
private IMessenger _mockMessenger;
public TestMessenger(IMessenger mock) {
_mockMessenger = mock;
}
public override void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action) {
_mockMessenger.Register<TMessage>(recipient, receiveDerivedMessagesToo, action);
}
public override void Register<TMessage>(object recipient, Action<TMessage> action) {
_mockMessenger.Register<TMessage>(recipient, action);
}
public override void Send<TMessage, TTarget>(TMessage message) {
_mockMessenger.Send<TMessage, TTarget>(message);
}
public override void Send<TMessage>(TMessage message) {
_mockMessenger.Send<TMessage>(message);
}
public override void Unregister<TMessage>(object recipient, Action<TMessage> action) {
_mockMessenger.Unregister<TMessage>(recipient, action);
}
public override void Unregister<TMessage>(object recipient) {
_mockMessenger.Unregister<TMessage>(recipient);
}
public override void Unregister(object recipient) {
_mockMessenger.Unregister(recipient);
}
}
Another approach that using constructor injection you can see in this answer. I think it's better to use constructor injection instead of using static Messenger.Default. It's more robust approach cause dependency injection providing natural seam with which you can easily substitute dependencies in unit tests. If you try to substitute static member call, then you rely on internal implementation that obviously can change.