How to chain constructors in Structuremap? - c#

Is there a way to chain the constructors in Structuremap? I would want a more succinct code - basically trying to get rid of the new keyword in codebase.
Currently what I have:
container.Configure(c =>
{
c.For<IDataContext>()
.Singleton()
.Use(new CarDataContextWrapper(new CarDataContext(Settings.Default.ConnectionString)
{
CommandTimeout = 60
}));
});
To inject in the constructor parameters, I would want to using .Ctor declaration. But how would I do it for the second class that I want to initialize?
container.Configure(c =>
{
c.For<IDataContext>()
.Use<CarDataContextWrapper>()
.Ctor<CarDataContext>().Is(x=>); // HOW TO SET THIS?
});

container.Configure(c =>
{
c.For<IDataContext>()
.Use<CarDataContextWrapper>("getting context", ctx=>
{
return ctx.GetInstance<CarDataContextWrapper>();
});
// Also need to tell SM how to build CarDataContextWrapper
});

Related

SimpleInjector Lazy in a Reflection

We are using SimpleInjector as a Dependency Injector, and we are registering all interface types using assembly iteration.
public static void RegisterInterfaceTypes(this Container container, Assembly assembly)
{
assembly.GetExportedTypes()
.Select(t => new {
Type = t,
Interface = t.GetInterfaces().FirstOrDefault()
})
.ToList()
.ForEach(t =>
{
container.Register(t.Interface, t.Type, Lifestyle.Transient);
});
}
We also have lazy classes to register. We can register these classes like below one by one. But we want to register all lazy types with similar iteration using reflection.
container.Register(() => new Lazy<ICommonBusiness>(container.GetInstance<CommonBusiness>));
You can make use of the ResolveUnregisteredType extension method to make last-minute registrations for resolve Lazy<T> dependencies:
Source:
public static void AllowResolvingLazyFactories(this Container container)
{
container.ResolveUnregisteredType += (sender, e) =>
{
if (e.UnregisteredServiceType.IsGenericType &&
e.UnregisteredServiceType.GetGenericTypeDefinition() == typeof(Lazy<>))
{
Type serviceType = e.UnregisteredServiceType.GetGenericArguments()[0];
InstanceProducer registration = container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
Type lazyType = typeof(Lazy<>).MakeGenericType(serviceType);
var factoryDelegate = Expression.Lambda(funcType, registration.BuildExpression()).Compile();
var lazyConstructor = (
from ctor in lazyType.GetConstructors()
where ctor.GetParameters().Length == 1
where ctor.GetParameters()[0].ParameterType == funcType
select ctor)
.Single();
var expression = Expression.New(lazyConstructor, Expression.Constant(factoryDelegate));
var lazyRegistration = registration.Lifestyle.CreateRegistration(
serviceType: lazyType,
instanceCreator: Expression.Lambda<Func<object>>(expression).Compile(),
container: container);
e.Register(lazyRegistration);
}
};
}
Usage:
container.AllowResolvingLazyFactories();
But please note the warnings from the documentation:
Warning: Registering [Lazy<T>] by default is a design smell. The use of [Lazy<T>] makes your design harder to follow and your system harder to maintain and test. Your system should only have a few of those [...] at most. If you have many constructors in your system that depend on a [Lazy<T>], please take a good look at your dependency strategy. The following article goes into details about why [this is] a design smell.
Warning: [...] the constructors of your components should be simple, reliable and quick (as explained in this blog post by Mark Seemann). That would remove the need for lazy initialization. For more information about creating an application and container configuration that can be successfully verified, please read the How To Verify the container’s configuration.

Unable to verify a call to a method on the mocked object with multiple interface

I'm trying to write unit test for TranslateResponse().
private async Task TranslateResponse(Policy policy)
{
foreach(t in translatorFactory.BuildTranslator())
{
var policyTranslator=t as IPolicyAwareTranslator;
policyTranslator?.SetPolicy(policy);
}
}
The TranslateResponse() has many other translators though, but for now, I limited it to just one.
The BuildTranslator is as
public async Task<List<ITranslator>> BuildTranslators()
{
return new List<ITranslator>()
{
new PolicyTranslator()
}
}
Here I'm returning the PolicyTranslator which implements ITranslator and IPolicyAwareTranslator
ITranslator has Translate() while IPolicyAwareTranslator has SetPolicy(Policy policy) respectively.
Now that for Unit testing, I create a Mock of ITranslator and set it up and I create the Mock of IPolicyTranslator via As<>.
Mock<ITranslator> mockedTranslator=new Mock<ITranslator>();
mockedTranslator.Setup(t => t.Translate(_translatorDataAccessor.Object));
var mockedPolicyTranslator = mockedTranslator.As<IPolicyAwareTranslator>();
mockedPolicyTranslator.Setup(t => t.SetPolicy(It.IsAny<Policy>()));
List<ITranslator> translators = new List<ITranslator>(new List<ITranslator>() { mockedTranslator.Object });
translatorFactory.Setup(t => t.BuildTranslators(It.IsAny<string>())).ReturnsAsync(translators);
Still the verify call fails.
I'm I going in the right direction or missing something?
mockedPolicyTranslator.Verify(t => t.SetPolicy(new UnknownPolicy()), Times.AtLeastOnce);
The argument matcher will need to be loosened
mockedPolicyTranslator.Verify(t => t.SetPolicy(It.IsAny<UnknownPolicy>()), Times.AtLeastOnce);
since currently used new UnknownPolicy() instance wont match whatever is passed while testing

How to call functions from data structure?

I would like to be able to describe some actions as function calls represented in a datastructure. Then I would like to be able to loop through the data structure and call the functions.
This pseudo-code describes what I would like to achieve:
static void Main(string[] args)
{
Action[] actions = new Action[]
{
new Action(DoAction1(5)),
new Action(DoAction1(7)),
new Action(DoAction2("100201")),
};
foreach (Action action in actions)
{
action.<Run the action function>;
}
}
public static void DoAction1(int x)
{
}
public static void DoAction2(string x)
{
}
It kind of looks like delegates, but not quite.
Any ideas on how to achieve this?
This is what you're looking for?
Action[] actions = new Action[]
{
new Action(()=>DoAction1(5)),
new Action(()=>DoAction1(7)),
new Action(()=>DoAction2("100201"))
};
foreach (Action action in actions)
{
action();
}
The Action class in .net allows you to directly assign lambdas
var actions = new List<Action>
{
() => DoAction1(5),
() => DoAction1(7),
() => DoAction2("100201"),
};
then executing an array of actions can be done like :-
actions.ForEach(a => a());
then you can add more actions to the list
actions.Add(() => DoAction2("blah blah"));
may be you can use reflection
var methodNames = typeof(MyType).GetMethods(BindingFlags.Public |
BindingFlags.Static)
.Select(x => x.Name)
.Distinct()
.OrderBy(x => x);
OR
foreach (var property in yourObject.GetType().GetProperties())
{
if (property.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
{
foreach (var item in (IEnumerable)property.GetValue(yourObject, null))
{
//do stuff
}
}
}
Since you seem not to want to use the Action class, you can check out the SharpByte codebase, specifically the SharpByte.Dynamic namespace. It allows evaluating statements and executing scripts with just a single method call, like this:
someContextObject.Execute("[executable code here]");
However, you can use it another way which may be what you're looking for. When you execute one of those dynamic compilation/execution extension methods, here's what's actually happening (paraphrased):
IExecutable executable = ExecutableFactory.Default.GetExecutable(ExecutableType.Script, "[source code here]", optionalListOfParameterNames, optionalListOfNamespaces);
If you wanted to evaluate an expression/function instead of run multiple-lined statements, you'd use ExecutableType.Expression . The main point is that you can keep a reference around to an IExecutable object and run it as many times as you like, passing different parameter values each time. You can also copy IExecutable objects freely using the .Copy() method of each; they are designed to be thread-safe but lightweight, and references or copies could thus be placed in a data structure for further (re)use. This post explains a bit more.

How to mock an interface returned as property from another mock?

I have the following interfaces:
interface IManufacturing
{
IJobApi JobApi {get;}
}
interface IJobApi
{
IList<JobSpec> GetSpecs (string wo, string name);
}
I have a class which uses IManufacturing and calls GetSpecs() like so:
var specs = _manufacturing.JobApi.GetSpecs (wo, name);
I setup my mocks like:
var jobApi = A.Fake<IJobApi> ();
A.CallTo (() => jobApi.GetSpecs (It.IsAny<string> (), It.IsAny<string> ()))
.Invokes (() => System.Diagnostics.Trace.WriteLine("GetSpecs called!"))
.Returns (new List<JobSpec>
{
new JobSpec("blablabla", "0.125", "something")
});
var manufacturing = A.Fake<IManufacturing> ();
A.CallTo (() => manufacturing.JobAPI)
.Invokes (() => System.Diagnostics.Trace.WriteLine ("JobAPI called!"))
.Returns (jobApi);
Upon running the test, I only see the "JobAPI called" string in the output.
So, the GetSpecs() does not get mocked and indeed the caller throws because it expected a list of specs whereas it received an empty string...
What could be the culprit here?
Thanks.
Dammit!
You're gonna laugh, I have!
Turned out that the following line
A.CallTo (() => jobApi.GetSpecs (It.IsAny<string> (), It.IsAny<string> ()))
was not correct for FakeItEasy. It should be written as
A.CallTo (() => jobApi.GetSpecs (A<string>.Ignored, A<string>.Ignored))
So, you may wonder why it did compile and run... Yeah me too. ;)
It.IsAny is for Moq (!)
I had a Using Moq lingering at the top of the class. (I'm in the process of switching to fakeiteasy from moq).
[face palm]
TGIF

How to add event listener via Fluent NHibernate?

I want to add an event listener (IPreUpdateEventListener) to add NHibernate but I can't seem to find an example when using a fluent configuration.
I want to be able to add the listener when I create the session factory, e.g. when the following code is execute.
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<IEntity>())
.BuildSessionFactory();
Anyone know how to do this?
So, late response, but for the sake of posterity, to add listeners without removing existing registration listeners (like the earlier answer from Bengt Be will do):
var config = new Configuration ();
config.AppendListeners (ListenerType.PreUpdate, new [] { new AuditEventListener () });
etc.
Late answer, found your question when I was trying to do the same. Found a solution that should work:
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>())
.ExposeConfiguration(c => c.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] {new AuditEventListener()});
Resurrecting the dead here but this:
........
.ExposeConfiguration(c => c.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] {new AuditEventListener()});
Should be:
.ExposeConfiguration(c => c.AppendListeners(ListenerType.PreUpdate, new object[]
{
new AuditEventListener()
});
I believe the 'SetListener' method (described in another answer) would also remove all previous listeners.
If you are into something a little more dynamic, you could do this:
private void AddListenerToConfiguration<T>(FluentConfiguration config, params ListenerType[] typesForListener)
where T : class
{
var listener = Activator.CreateInstance<T>();
config.ExposeConfiguration(x =>
{
foreach (var listenerType in typesForListener)
{
x.AppendListeners(listenerType, new T[]
{
listener
});
}
});
}
And then call something like this:
AddListenerToConfiguration<AuditEventListener>(smFactory,
ListenerType.PreUpdate);
This allows for cleaner code while you are looking at the Fluent configuration. It also allows you to easily register a single type to multiple listener types.
As for removing the default listeners, I wouldn't remove them unless I have a listener that inherits from the default listener implementation and calls base.METHODNAME on the overridden methods or replicates the same behavior as that of the default listeners.

Categories

Resources