I have an issue where I want to use StructureMap to create singletons, but instead StructureMap creates multiple instances. I get confused when trying to read through the documentation on StructureMap on how to handle generics properly.
I have to instantiate a repository for a given entity while providing an instance for the data connection that needs the type of the entity due to generics.
Here is my code for VendorRepository, and many other repositories are structured in the exact same way. IVendorRepository needs IRepository injected with the Vendor type. And I'm not quite sure how to accomplish that in a singleton way.
public interface IVendorRepository {
...
}
public class VendorRepository : IVendorRepository {
private readonly IRepository<Vendor> _repository;
public VendorRepository(IRepository<Vendor> repository)
{
_repository = repository;
}
...
}
public class Vendor : DomainEntity
{
...
}
public class DomainEntity : IDomainEntity
{
...
}
Here is the the data connection portion. SqlRepository handles the actual connection via the currentSession. As far as I can tell, each DomainEntity repository (such as VendorRepository) would need it's own instance of the SqlRepository.
public class SqlRepository<T> : IRepository<T> where T : class, IDomainEntity
{
private readonly ISession _currentSession;
public SqlRepository(ISession currentSession)
{
_currentSession = currentSession;
}
...
}
public interface IRepository<T> where T : IDomainEntity
{
...
}
And finally here is where everything gets wired up today. Using this code, every time VendorRepository is injected, a new instance is created.
For(typeof(IRepository<>)).Use(typeof(SqlRepository<>));
For<ISessionSource>()
.Use(context => ConfigurationSettings.RunAgainstLocalDatabase
? (ISessionSource) context.GetInstance<LocalSessionSource>()
: (ISessionSource) context.GetInstance<LiveSessionSource>());
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Use(context => context.GetInstance<ISessionSource>().OpenSession());
When I tried to use a singleton here, my currentSession was being closed by NHibernate.
For(typeof(IRepository<>)).Singleton().Use(typeof(SqlRepository<>));
Edit:
I'm not entirely sure if this would work as I have a large number of repositories and entities. But I'm currently attempting to add these in by hand to test and see if it would work or not. My end goal is to have singletons of all the entity repositories (such as VendorRepository).
For<IRepository<Vendor>>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new SqlRepository<Vendor>(
context.GetInstance<ISessionSource>().OpenSession()
));
Edit again:
This appears to be more accurate.. although I'm still not quite sure.
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Use(context => new VendorRepository(new SqlRepository<Vendor>(context.GetInstance<ISessionSource>().OpenSession())));
Final Edit:
Here is what needs to happen on a per repository basis. I have no idea how I can do this without listing out every repository as per below (~100). However, in limited testing, using singleton's instead of new instances for every dependency injection had no perceived performance increase. Unless there is an easier way to have StructureMap pick up the repositories and bind them automatically and correctly, I will just leave the way it is where it creates multiple instances as opposed to trying to list out ~100 nearly identical copies of the following code.
For<IVendorRepository>()
.HybridHttpOrThreadLocalScoped()
.Singleton()
.Use(context => new VendorRepository(
new SqlRepository<Vendor>(context.GetInstance<ISession>())
));
Related
I have a use case in which I want to create repository instances using .NET Core dependency injection, but need to change one of the constructor parameters at runtime. To be precise, the parameter that should be decided at runtime is the "database connection", which will point to one or another database decided by the caller. This type, by the way, is not registered with the DI container, but all the others are.
The caller will use a repository factory type to create the repository with the desired connection.
It looks something like this:
class ARepository : IARepository
{
public ARepository(IService1 svc1, IService2 svc2, IConnection connection) { }
public IEnumerable<Data> GetData() { }
}
class RepositoryFactory : IRepositoryFactory
{
public RepositoryFactory(IServiceProvider serviceProvider) =>
_serviceProvider = serviceProvider;
public IConnection CreateAlwaysFresh<TRepository>() =>
this.Create<TRepository>(new FreshButExpensiveConnection());
public IConnection CreatePossiblyStale<TRepository>() =>
return this.Create<TRepository>(new PossiblyStaleButCheapConnection());
private IConnection Create<TRepository>(IConnection conn)
{
// Fails because TRepository will be an interface, not the actual type
// that I want to create (see code of AService below)
return ActivatorUtilities.CreateInstance<TRepository>(_serviceProvider,conn);
// Fails because IConnection is not registered, which is normal
// because I want to use the instance held in parameter conn
return _serviceProvider.GetService<TRepository>();
}
}
The following types were registered:
services.AddTransient<IARepository, ARepository>(); // Probably not needed
services.AddTransient<IService1, Service1>();
services.AddTransient<IService2, Service2>();
services.AddTransient<IRepositoryFactory, RepositoryFactory>();
And the factory would be used as such:
class AService
{
public AService(IRepositoryFactory factory)
{
_factory = factory;
}
public void ExecuteCriticalAction()
{
var repo = _factory.CreateAlwaysFresh<IARepository>();
// Gets the freshest data because repo was created using
// AlwaysFresh connection
var data = repo.GetData();
// Do something critical with data
}
public void ExecuteRegularAction()
{
var repo = _factory.CreatePossiblyStale<IARepository>();
// May get slightly stale data because repo was created using
// PossiblyStale connection
var data = repo.GetData();
// Do something which won't suffer is data is slightly stale
}
}
One of the reasons why I've kept all the code based on interfaces is, of course, for unit testing. However, as you can see from the pseudo-implementation of RepositoryFactory.Create<TRepository>, this is also a problem because I reach a point where I need to either :
determine the concret type associated to IARepository in the DI container to pass it to ActivatorUtilities in order to create an instance of it using the desired value of IConnection while resolving other constructor parameters with IServiceProvider, or
somehow tell IServiceProvider to use a particular instance of IConnection when getting a particular service
Is this at all possible using .NET Core DI?
(Bonus question: Should I have used another, simpler, approach?)
Update: I edited the sample code a little to hopefully make my intentions more clear. The idea is to allow the same repository, exact same code, to use different connections (which are configured during app startup) depending on the caller's specific needs. To summarise:
a Repository's responsibility is to execute the correct queries on a Connection when an action is requested.
the Caller will act on the data returned by the repository
however, the Caller might require the Repository to execute its queries on a particular Connection (which, in this example, controls data freshness)
Several workarounds have come up to the problem of injecting the right connection in the factory:
add a mutable Connection property to the Repositories and set it right after creation => what bothers me most with this solution is that it makes it very easy to forget to set a connection, for example in test code. It also leaves a door open to change a property of the repository which should be immutable.
do not inject the Connection in the class, but pass it as a method parameter instead => this makes for a less elegant API, since every method will now have an "extra" parameter, which could've been simply provided to the class to begin with, and the extra parameter is but an "implementation detail"
Since the IConnection will not be created by the DI, you could remove it from the repository constructor and have it as a property, then on your factory you can assign its value after the creation:
interface IARepository
{
IConnection Connection { set; }
}
class ARepository : IARepository
{
public IConnection Connection { private get; set; }
public ARepository(IService1 svc1, IService2 svc2)
{ /* ... */ }
}
class RepositoryFactory : IRepositoryFactory
{
/* ... */
private IConnection Create<TRepository>(IConnection conn)
where TRepository : IARepository
{
var svc = _serviceProvider.GetService<TRepository>();
svc.Connection = conn;
return svc;
}
}
The issue is in registering and attempting to inject IRepository at all. By your own spec, the repo cannot be created via dependency injection because the connection passed into it will vary at runtime. As such, you should create a factory (which you've already done) and register and inject that instead. Then, you pass in the connection to your Create method.
public TRepository Create<TRepository>(IConnection conn)
where TRepository : IRepository, new()
{
return new TRepository(conn);
}
You'll likely want to do some sort of instance locator pattern here instead. For example, you might store the created instance in a ConcurrentDictionary keyed by the connection. Then, you'd return from the dictionary instead. It's probably not a huge deal if the repository actually gets instantiated multiple times in race conditions - should just be a fairly minor object allocation. However, you can employ SemaphoreSlim to create locks when accessing the ConcurrentDictionary, to prevent this.
You haven't given a ton of info about your specific use case, so I'll also add a potential alternate solution. For this to work, the connection has to be defined by config or something. If it truly is runtime-provided, this won't work, though. You can provide an action to the service registration, for example:
services.AddScoped<IRepository, ARepository>(p => {
// create your connection here
// `p` is an instance of `IServiceProvider`, so you can do service lookups
return new ARepository(conn);
});
Hi this might be trivial but I am trying to understand the class instantiation using interface. So below is my code:
public interface IRepository
{
string GetMemberDisplayName();
}
public class Repository : IRepository
{
private readonly Manager _manager;
public Repository() {}
public Repository(string connectionName)
{
_manager = new Manager(connectionName);
}
public string GetMemberDisplayName(string ID)
{
return "FooFoo";
}
}
Now in another class that uses the repository class functionality has instantiated it as follows:
public class LogServiceHelper
{
readonly IRepository _alrAttendance;
readonly IRepository _alrUsers;
public LogServiceHelper()
{
_alrAttendance = new Repository("value1");
_alrUsers = new Repository("value2");
}
public string GetMemberName(string empId)
{
return _alrUsers.GetMemberDisplayName(empId);
}
}
My question is if this is correct way to instantiate a class with parameterized constructor. And if yes, then second question is why do we need interface in this case. We could directly instantiate the class without creating the interface?
Yes, that's how to invoke a parameterized constructor, but no, that's not what you should be doing.
As you have it, LogServiceHelper has a hard dependency on the Repository class, and so you are right, the interfaces don't buy you anything. However, if they were injected:
public LogServiceHelper(IRepository attendanceRepo, IRepository userRepo)
{
_alrAttendance = attendanceRepo;
_alrUsers = userRepo;
}
You suddenly gain the benefits of abstraction. Notably that a unit test could pass in fake repositories, and that you can switch to another implementation of IRepository without changing LogServiceHelper.
The next question is then "Who creates the Repository concrete class?". For that, I refer you to the variety of DI/IoC containers out there, such as Autofac, Unity, and NInject.
We could directly instantiate the class without creating the
interface?
This is indeed true and it might work without any problem. But then we are coming to the crucial questions:
Is my code testable, how would I test this piece of code?
Could I easily change the behavior without changing LogServiceHelper
If you don't rely on the abstraction, the answer to the above questions is unfortunately, no. Luckily there is something called SOLID and the D stands for Dependency Injection Principle.
public LogServiceHelper(IRepository alrAttendance, IRepository alrUsers)
{
_alrAttendance = alrAttendance;
_alrUsers = alrUsers;
}
So, with this simple change, you made decoupling of the moduls and all of a sudden you are relying on the abstraction which gains a lot of benefits to design.
Before I begin my question, here is a background of my application:
Application: Web Application using ASP.NET MVC and C#
ORM: Entity Framework
Dependency injection container: Autofac
Consider I have a class that only serves as a lookup class for database tables. My database contains about 350 tables. The following is a simplified example that shows exactly the structure in my application.
(if you think you've got the scenario, you can directly jump to the Question at the bottom.)
Here is the lookup class
public class Lookup
{
private readonly IRepository<Table001> _table001Repository;
// repositories Table002 to Table349
private readonly IRepository<Table350> _table350Repository;
public Lookup(
IRepository<Table001> table001Repository,
// parameters table002Repository to table349Repository
IRepository<Table350> table350Repository)
{
_table001Repository = table001Repository;
// assignments for table002Repository to table349Repository
_table350Repository = table350Repository;
}
public Table001 GetTable001(/* fields for looking up Table001 */)
{
// lookup logic using the repository for Table001, namely _table001Repository
}
// other lookup methods for Table002 to Table349
public Table350 GetTable350(/* fields for looking up Table350 */)
{
// lookup logic using the repository for Table350, namely _table350Repository
}
}
Now, an example class that uses this Lookup class:
public class MyClass
{
private readonly ILookup _lookup;
public MyClass(ILookup lookup)
{
_lookup = lookup;
}
public Method()
{
Table001 table001 = _lookup.GetTable001(/* fields */);
Table002 table002 = _lookup.GetTable002(/* fields */);
Table003 table003 = _lookup.GetTable003(/* fields */);
...
}
}
Registrations to Autofac are done this way:
// Lookup class registration
builder.RegisterType<Lookup>().As<ILookup>().InstancePerLifetimeScope();
// generic registration for Repositories
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();
Question:
As you can see, the class that actually makes use of the Lookup class is using only three methods from 350 lookup methods. But while instantiating Lookup class in MyClass (the _lookup field), all 350 repositories are resolved too, instantiating 350 repositories. Now my concern is regarding performance/efficiency. Which of the following two options is better performance wise, and why?
Resolving dependencies as is being done now, that is using auto-injection in the constructor.
Resolving the repository only in the method that actually uses the repository instead of auto-injection in the constructor. For example GetTable001() would become this (the field _table001Repository will be removed from Lookup class, so will be the parameter table001Repository in its constructor):
public Table001 GetTable001(/* fields for looking up Table001 */)
{
IRepository<Table001> table001Repository = container.Resolve<IRepository<Table001>>();
// lookup logic
}
In option 1, all 350 repositories are instantiated while resolving _lookup, even though, for example, the class MyClass uses only three lookup methods. Is the second approach any better than the first? Or, is the first option actually better than the second performance-wise? Also, does the scope of resolution (InstancePerLifetimeScope, InstancePerDependency, etc.) make any difference?
Thanks.
PS: please comment if you think this question should better be posted in SoftwareEngineering. The reason of asking it here is the broad audience SO has.
There are a few different things to consider here:
First, is anything else using the ILookup instance? If so, you already have an instance of those 350 repositories created, so it doesn't really matter in that respect.
Second, non constructor resolution of injected members (e.g. using ServiceLocator) is considered an anti-pattern (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/). Thus, I would try to avoid if possible. The biggest reason why (as outlined in the article) is that it hides class dependencies from their consumers.
Third, is there any reason you cannot create a new service which consists of only the necessary repository as a dependency? If you can create an IMyClassLookup service which implements the ILookup interface that has only the necessary repositories you need, that's definitely the easiest and cleanest way to go. Then you would just register your new service and use it in your constructor:
New Interface
public interface IMyClassLookup : ILookup
{
}
New Class
public class MyClassLookup : IMyClassLookup
{
private readonly IWhateverRepository _whateverRepository;
public MyClassLookup(IWhateverRepository whateverRepository)
{
_whateverRepository = whateverRepository;
}
// IMyClassLookup implementations here that use _whateverRepository
}
Dependency registration
builder.RegisterType<MyClassLookup>().As<IMyClassLookup>().InstancePerLifetimeScope();
Your class
public class MyClass
{
private readonly IMyClassLookup _myClassLookup;
public MyClass(IMyClassLookup myClassLookup)
{
_myClassLookup = myClassLookup;
}
public Method()
{
Table001 table001 = _myClassLookup.GetTable001(/* fields */);
Table002 table002 = _myClassLookup.GetTable002(/* fields */);
Table003 table003 = _myClassLookup.GetTable003(/* fields */);
...
}
}
Seem like Lookup class itself is a Service Locator Pattern.
IRepository<Table001> table001Repository = container.Resolve<IRepository<Table001>>();
Service Locator has few problems. One of them is it doesn't follow Don't call us, we'll call you principle. It directly ask for the things we need rather than handed them to us.
With the service locator, we have to examine the code, searching for capricious calls that retrieve a required service. Constructor injection allowed us to view dependencies—all of them—with a glance at the constructor, or at a distance, via IntelliSense.
Solution
Ideally, you want to inject IRepository<Table001> to MyClass. I also use the similar approach in my projects.
public class MyClass
{
private readonly IRepository<Table001> _table001;
public MyClass(IRepository<Table001> table001)
{
_table001 = table001;
}
}
If you see yourself injecting a lot of dependencies into a single class, it might be that the class violates Single Responsibility Principle. You might want to separate it to different classes.
"creating an object instance is something the .NET Framework does extremely fast. Any performance bottleneck your application may have
will appear in other places." - Mark Seemann author of Dependency
Injection in .Net
I'm brand new to using Simple Injector although I have been using Ninject for a long time, so I am comfortable with DI in general. One thing that attracted me to want to use Simple Injector was the ease of use of Decorators.
I have been able to successfully use decorators with Simple Injector in all normal cases where the dependencies are resolved when the service is requested. However, I am having a hard time figuring out if there is a way to get my decorators applied in a case when the service must be constructed using a runtime value.
In Ninject, I could pass a ConstructorArgument to the kernel.Get<IService> request that could be inherited down the chain of N decorators all the way to the "real" implementing class. I cannot figure out a way to replicate that using Simple Injector.
I have put some very basic code below to illustrate. What I would want to do in the real world would be to pass an IMyClassFactory instance into other classes in my application. Those other classes could then use it to create IMyClass instances using the IRuntimeValue they would provide. The IMyClass instance they got from the IMyClassFactory would be decorated automatically by the registered decorators.
I know I could manually apply my decorator(s) in my IMyClassFactory or any Func<IMyClass> I could come up with, but I would like it to "just work".
I keep going around and around trying to abstract out the MyClass construction, but I can't figure out how to get it to resolve with the IRuntimeValue constructor argument and be decorated.
Am I overlooking an obvious solution?
using System;
using SimpleInjector;
using SimpleInjector.Extensions;
public class MyApp
{
[STAThread]
public static void Main()
{
var container = new Container();
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof (IMyClass), typeof (MyClassDecorator));
container.Register<Func<IRuntimeValue, IMyClass>>(
() => r => container.GetInstance<IMyClassFactory>().Create(r));
container.Register<IMyClass>(() => ?????)); // Don't know what to do
container.GetInstance<IMyClass>(); // Expect to get decorated class
}
}
public interface IRuntimeValue
{
}
public interface IMyClass
{
IRuntimeValue RuntimeValue { get; }
}
public interface IMyClassFactory
{
IMyClass Create(IRuntimeValue runtimeValue);
}
public class MyClassFactory : IMyClassFactory
{
public IMyClass Create(IRuntimeValue runtimeValue)
{
return new MyClass(runtimeValue);
}
}
public class MyClass : IMyClass
{
private readonly IRuntimeValue _runtimeValue;
public MyClass(IRuntimeValue runtimeValue)
{
_runtimeValue = runtimeValue;
}
public IRuntimeValue RuntimeValue
{
get
{
return _runtimeValue;
}
}
}
public class MyClassDecorator : IMyClass
{
private readonly IMyClass _inner;
public MyClassDecorator(IMyClass inner)
{
_inner = inner;
}
public IRuntimeValue RuntimeValue
{
get
{
return _inner.RuntimeValue;
}
}
}
Edit 1:
Ok, thanks to Steven for the great answer. It has given me a couple of ideas.
Maybe to make it a little more concrete though (although not my situation, more "classic"). Say I have an ICustomer that I create at runtime by reading a DB or deserializing from disk or something. So I guess that would be considered a "newable" to quote one of the articles Steven linked. I would like to create an instance of ICustomerViewModel so I can display and manipulate my ICustomer. My concrete CustomerViewModel class takes in an ICustomer in its constructor along with another dependency that can be resolved by the container.
So I have an ICustomerViewModelFactory that has a .Create(ICustomer customer) method defined which returns ICustomerViewModel. I could always get this working before I asked this question because in my implementation of ICustomerViewModelFactory I could do this (factory implemented in composition root):
return new CustomerViewModel(customer, container.GetInstance<IDependency>());
My issue was that I wanted my ICustomerViewModel to be decorated by the container and newing it up bypassed that. Now I know how to get around this limitation.
So I guess my follow-up question is: Is my design wrong in the first place? I really feel like the ICustomer should be passed into the constructor of CustomerViewModel because that demonstrates intent that it is required, gets validated, etc. I don't want to add it after the fact.
Simple Injector explicitly lacks support for passing on runtime values through the GetInstance method. Reason for this is that runtime values should not be used when the object graph is constructed. In other words, the constructors of your injectables should not depend on runtime values. There are several problems with doing that. First of all, your injectables might need to live much longer than those runtime values do. But perhaps more importantly, you want to be able to verify and diagnose your container's configuration and that becomes much more troublesome when you start using runtime values in the object graphs.
So in general there are two solutions for this. Either you pass on the runtime value through the method call graph or you create a 'contextual' service that can supply this runtime value when requested.
Passing on the runtime value through the call graph is especially a valid solution when you practice architectures like this and this where you pass on messages through your system or when the runtime value can be an obvious part of the service's contract. In that case it is easy to pass on the runtime value with the message or the method and this runtime value will also pass through any decorator on the way through.
In your case this would mean that the factory creates the IMyService without passing in the IRuntimeValue and your code passes this value on to the IMyService using the method(s) it specifies:
var service = _myServiceFactory.Create();
service.DoYourThing(runtimeValue);
Passing through the runtime value through the call graph however is not always a good solution. Especially when this runtime value should not be part of the contract of the message that is sent. This especially holds for contextual information use as information about the current logged in user, the current system time, etc. You don't want to pass this information through; you just want it to be available. We don't want this, because this would give an extra burden to the consumers of passing the right value every time, while they probably shouldn't even be able to change this information (take the user in who's context the request is executed for instance).
In that case you should define service that can be injected and allows retrieving this context. For instance:
public interface IUserContext {
User CurrentUser { get; }
}
public interface ITimeProvider {
DateTime Now { get; }
}
In these cases the current user and the current time aren't injected directly into a constructor, but instead these services are. The component that needs to access the current user can simply call _userContext.CurrentUser and this will be done after the object is constructed (read: not inside the constructor). Thus: in a lazy fashion.
This does mean however that the IRuntimeValue must be set somewhere before MyClass gets invoked. This probably means you need to set it inside the factory. Here's an example:
var container = new Container();
var context = new RuntimeValueContext();
container.RegisterSingle<RuntimeValueContext>(context);
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof(IMyClass), typeof(MyClassDecorator));
container.Register<IMyClass, MyClass>();
public class RuntimeValueContext {
private ThreadLocal<IRuntimeValue> _runtime;
public IRuntimeValue RuntimeValue {
get { return _runtime.Value; }
set { _runtime.Value = value; }
}
}
public class MyClassFactory : IMyClassFactory {
private readonly Container _container;
private readonly RuntimeValueContext context;
public MyClassFactory(Container container, RuntimeValueContext context) {
_container = container;
_context = context;
}
public IMyClass Create(IRuntimeValue runtimeValue) {
var instance = _container.GetInstance<IMyClass>();
_context.RuntimeValue = runtimeValue;
return instance;
}
}
public class MyClass : IMyClass {
private readonly RuntimeValueContext _context;
public MyClass(RuntimeValueContext context) {
_context = context;
}
public IRuntimeValue RuntimeValue { get { return _context.Value; } }
}
You can also let the MyClass accept the IRuntimeValue and make the following registration:
container.Register<IRuntimeValue>(() => context.Value);
But the disallows verifying the object graph, since Simple Injector will ensure that registrations never return null, but context.Value will be null by default. So another option is to do the following:
container.Register<IMyClass>(() => new MyClass(context.Value));
This allows the IMyClass registration to be verified, but will during verification still create a new MyClass instance that is injected with a null value. If you have a guard clause in the MyClass constructor, this will fail. This registration however disallows MyClass to be auto-wired by the container. Auto-wiring that class can come in handy when you've got more dependencies to inject into MyClass for instance.
I have a wcf service and on the client i have:
var service = new ServiceReference1.CACSServiceClient()
The actual service code is:
public CACSService() : this(new UserRepository(), new BusinessRepository()) { }
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
So, all this works fine, but i don't like how i am newing up all the repositories at the same time because the client code might not need to new up the UserRepository and only interested in newing up the BusinessRepository. So, is there a way to pass in something to this code:
var service = new ServiceReference1.CACSServiceClient()
to tell it which repository to new up based on the code that is calling the service or any other advice i need to go about when designing the repositories for my entity framework. Thankx
The beauty of pure DI is that you shouldn't worry about the lifetimes of your dependencies, because these are managed for you by whoever supply them (a DI Container, or some other code you wrote yourself).
(As an aside, you should get rid of your current Bastard Injection constructors. Throw away the parameterless constructor and keep the one that explicitly advertises its dependencies.)
Keep your constructor like this, and use _IRepository and _IBusinessRepository as needed:
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
If you worry that one of these repositories are not going to be needed at run-time, you can inject a lazy-loading implementation of, say, IUserRepsository instead of the real one you originally had in mind.
Let's assume that IUserRepository looks like this:
public interface IUserRepository
{
IUser SelectUser(int userId);
}
You can now implement a lazy-loading implementation like this:
public class LazyUserRepository : IUserRepository
{
private IUserRepository uRep;
public IUser SelectUser(int userId)
{
if (this.uRep == null)
{
this.uRep = new UserRepository();
}
return this.uRep.SelectUser(userId);
}
}
When you create CACService, you can do so by injecting LazyUserRepository into it, which ensures that the real UserRepository is only going to be initialized if it's needed.
The beauty of this approach is that you don't have to do this until you need it. Often, this really won't be necessary so it's nice to be able to defer such optimizations until they are actually necessary.
I first described the technique of Lazy Dependencies here and here.
Instead of instantiating ("newing up") the repositories on construction, you could lazy load them in their properties. This would allow you to keep your second constructor, but have your first constructor do nothing.
The user could then assign these, as needed, otherwise.
For example:
public class CACSService
{
public CACSService() {}
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
private IUserRepository _IRepository;
public IUserRepository Repository
{
get {
if (this._IRepository == null)
this._IRepository = new UserRepository();
return this._IRepository;
}
}
// Add same for IBusinessRepository
}
Do your repositories have object-level state? Probably not, so create them as singletons and have a DI container provide them to CACService.
Otherwise, are they actually expensive to create? If not, creating a new one per request has negligible cost compared to the RPC and database operations.
Using the Ninject dependency injection container, your CACService might look like the following. Other DI containers have equally succinct mechanisms of doing this.
public class CACSService
{
public CACService
{
// need to do this since WCF creates us
KernelContainer.Inject( this );
}
[Inject]
public IUserRepository Repository
{ set; get; }
[Inject]
public IBusinessRepository BusinessRepository
{ set; get; }
}
And during your application startup, you would tell Ninject about these types.
Bind<IUserRepository>().To<UserRepository>().InSingletonScope();
Bind<IBusinessRepository>().To<BusinessRepository>().InSingletonScope();
Preface: This is a general guide to dependency inversion. If you need the default constructor to do the work (e.g. if it is new'ed up by reflection or something else), then it'll be harder to do this cleanly.
If you want to make your application configurable, it means being able to vary how your object graph is constructed. In really simple terms, if you want to vary an implementation of something (e.g. sometimes you want an instance of UserRepository, other times you want an instance of MemoryUserRepository), then the type that uses the implementation (CACService in this case) should not be charged with newing it up. Each use of new binds you to a specific implementation. Misko has written some nice articles about this point.
The dependency inversion principle is often called "parametrise from above", as each concrete type receives its (already instantiated) dependencies from the caller.
To put this into practice, move the object creation code out of the CACService's parameterless constructor and put it in a factory, instead.
You can then choose to wire up things differently based on things like:
reading in a configuration file
passing in arguments to the factory
creating a different type of factory
Separating types into two categories (types that create things and types that do things) is a powerful technique.
E.g. here's one relatively simple way of doing it using a factory interface -- we simply new up whichever factory is appropriate for our needs and call its Create method. We use a Dependency Injection container (Autofac) to do this stuff at work, but it may be overkill for your needs.
public interface ICACServiceFactory
{
CACService Create();
}
// A factory responsible for creating a 'real' version
public class RemoteCACServiceFactory : ICACServiceFactory
{
public CACService Create()
{
return new CACService(new UserRepository(), new BusinessRepository());
}
}
// Returns a service configuration for local runs & unit testing
public class LocalCACServiceFactory : ICACServiceFactory
{
public CACService Create()
{
return new CACService(
new MemoryUserRepository(),
new MemoryBusinessRepository());
}
}