While the concept of IoC isn't foreign to me, I'm new to Unity and I'm having trouble connecting the metaphorical dots, so to speak.
In our project we have a class library for logic, then several class libraries with repositories implementing common interfaces (they provide access and allow CRUD operations on different data sources). Finally, this is all used together in either an MVC web site or a SharePoint site.
We wanted to implement Unity to keep a single configuration and make the whole thing better.
But... there are some design issues I'm facing. For example - the MVC web site, as far as communicating with the underlying SQL database is concerned, can have everything it needs specified in the configuration section for the Unity container. However, said web site also needs to occasionally connect with SharePoint... in order to create a SharePoint repository, I need to create an SPWeb
object and pass it to the repository constructor.
I CAN do that using ParameterOverride
when resolving the type, but this doesn't... feel right. There are cases where a larger number of parameters need to overridden this way; to resolve a logic class I need to pass repositories, which in turn are resolved by passing a manually created SPWeb
object... When this happens it seems I'm no longer following an IoC pattern. The kicker here is that I cannot have the SPWeb
object defined in the Unity container!
Is there a pattern (a practical example would be superb) where Unity is used but certain values are being passed TO the container while resolving types, without the need to use ParameterOverride
?
EDIT
I feel I need to provide a more specific example of why ParameterOverride
is a problem. Below is a fragment of code used by a SharePoint timer job. The job in question synchronizes some data between SharePoint and SQL, so it requires two different repositories implementing the same interface. Because the code is ran from SharePoint, it cannot access a global configuration defined DataContext
(EntityFramework, code-first) because there's no web.config
file to read the connection string from. Also, due to the weirdness that is SharePoint, I cannot "get" the current SPWeb
object, and instead need to create it on the fly.
The end result is a ton on using
statements, and a lot of parameters need to overridden when using Resolve
. Also, the need to pass the parameter NAME as a string would make this really difficult to code for anyone else - this information isn't known from the interface alone.
public override void Execute(Guid targetInstanceId)
{
var siteUrl = Properties["Site"] as string;
var sqlConnection = Properties["SQL"] as string;
if (String.IsNullOrEmpty(siteUrl))
throw new ArgumentNullException("Site URL is missing.");
if (String.IsNullOrEmpty(sqlConnection))
throw new ArgumentNullException("SQL connection string is missing.");
using (var site = new SPSite(siteUrl, SPUserToken.SystemAccount))
using (var web = site.OpenWeb())
using (var spPollRepository = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<IPollRepository>(new ParameterOverride("web", web)))
using (var ctx = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<Repositories.PollsDataContext>(Configuration.ServiceLocator.SqlNamedRegistration, new ParameterOverride("nameOrConnectionString", sqlConnection), new ParameterOverride("initialize", false)))
using (var sqlPollRepository = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<IPollRepository>(Configuration.ServiceLocator.SqlNamedRegistration, new ParameterOverride("ctx", ctx)))
{
IPollsSyncLogic logic = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<Logic.IPollsSyncLogic>(new ParameterOverride("sqlRepository", sqlPollRepository), new ParameterOverride("spRepository", spPollRepository));
logic.SyncPolls();
}
}
There's a big chance I'm using Unity... wrong. Or that some other fundamental definition has been mixed up. I hope this clears up any confusion regarding the question.
SPWeb
because in these casesSPContext.Current
is unavailable... – Shaamaan Nov 19 '14 at 14:49