Is there any potential problem in setting datacontext as property like this:
repository
public Repository()
{
public DataContext dc {get;set;}
public GetOrders(int id)
{ ...from dc.Orders...}
}
service layer:
public GetNewOrders()
{
....
Repository rep=new Repository();
using {DataContext dc=new DataContext())
{
rep.dc=dc;
rep.GetOrders(id);
}
}
From what I have read, using the DataContext "for more than one business conversation is usually the wrong thing to do." Scroll down to the Why Is This Important? section for the quote. Due to caching and other factors, you should consider your DataContext stale immediately. From that, it is safe to say you don't want to keep the DataContext as a property that is reused by all your methods. Using Eric Duncan's suggestion, you will want to pass in some kind of DataContext factory to get a new context for each query.
For a discussion focused on the DataContext, the APress Pro LINQ book has an entire chapter on the DataContext, the very last page of which also advises you to "consider the DataContext stale immediately."
In DDD, you're missing the bigger picture here by referencing the concret classes. You are not interfacing between the Repository and "Services layer" by best practices. If you must have DataContext injected into the Repository, I would recommend refactoring to:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
The better solution would be to let the Repository handle the DataContext on its own - keeping the seperation of concert valid by masking the underlying requirements:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(String connectionString)
{
_dataContext = new DataContext(connectionString);
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
If you must keep control of the DataContext (or another class) yourself (perhaps you want to keep a static reference around, or change settings based on an WebRequest, etc), you you will need to use a "Factory".
The factory would look something like this:
public static class DataContextFactory
{
public static IDataContext GetInstance()
{
// return either a static instance,
// or threaded instance, a GlobalContext instance
// or whatever your preference is here
//
}
}
That way, you have full control over how the instance of DataContext is controlled outside and away from your "Services" layer. So, you would use this DataContextFactory like the following:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
public IList<Orders> GetNewOrders()
{
using (var dataContext = DataContextFactory.GetInstance())
{
// dataContext is now your IDataContext to work with
}
}
}
"How to access the IRepository?" you may ask?
Your services layer would do something like:
public void GetNewOrdersForServices()
{
// Not recommended!
// IRepository repo = new Repository()
//
// The following is recommended instead; because, it removes the
// the Concret reference from your Services layer completely!
//
IRepository repo = ServiceLocator.InstanceOf<IRepository>();
IList myList = repo.GetNewOrders();
}
Or, you would inject it into the constructor of your service using your favorite flavor of Inversion of Control container like so:
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
If you are not fimilar with the service locator concepts, check out Castle Windsor as it Encapsulates just about all your needs.
Related
I am trying to inject the IApplicationConfigurationSection implementation into this MVC5 Controller, so that I can have access to some of the information (various strings) from my web.config custom section in all of my views:
public class BaseController : Controller
{
public IApplicationConfigurationSection AppConfig { get; set; }
public BaseController()
{
ViewBag.AppConfig = AppConfig; // AppConfig is always null
}
}
I want to use setter injection so I don't have to clutter up my derived Controller constructors with parameters that they don't really care about.
Note: If there is a better way to inject base class dependencies, please let me know. I admit I may not be on the right track here.
In my Global.asax I load my StructureMap configurations:
private static IContainer _container;
protected void Application_Start()
{
_container = new Container();
StructureMapConfig.Configure(_container, () => Container ?? _container);
// redacted other registrations
}
My StructureMapConfig class loads my registries:
public class StructureMapConfig
{
public static void Configure(IContainer container, Func<IContainer> func)
{
DependencyResolver.SetResolver(new StructureMapDependencyResolver(func));
container.Configure(cfg =>
{
cfg.AddRegistries(new Registry[]
{
new MvcRegistry(),
// other registries redacted
});
});
}
}
My MvcRegistry provides the mapping for StructureMap:
public class MvcRegistry : Registry
{
public MvcRegistry()
{
For<BundleCollection>().Use(BundleTable.Bundles);
For<RouteCollection>().Use(RouteTable.Routes);
For<IPrincipal>().Use(() => HttpContext.Current.User);
For<IIdentity>().Use(() => HttpContext.Current.User.Identity);
For<ICurrentUser>().Use<CurrentUser>();
For<HttpSessionStateBase>()
.Use(() => new HttpSessionStateWrapper(HttpContext.Current.Session));
For<HttpContextBase>()
.Use(() => new HttpContextWrapper(HttpContext.Current));
For<HttpServerUtilityBase>()
.Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Server));
For<IApplicationConfigurationSection>()
.Use(GetConfig());
Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());
}
private IApplicationConfigurationSection GetConfig()
{
var config = ConfigurationManager.GetSection("application") as ApplicationConfigurationSection;
return config; // this always returns a valid instance
}
}
I have also "thrown my hands up" and tried using the [SetterProperty] attribute on the BaseController - that technique failed as well.
Despite my best efforts to find a solution, the AppConfig property in my controller's constructor is always null. I thought that
`Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());`
would do the trick, but it didn't.
I have found that if I discard setter injection and go with constructor injection, it works as advertised. I'd still like to know where I'm going wrong, but I'd like to stress that I'm not a StructureMap guru - there may be a better way to avoid having to constructor-inject my base class dependencies. If you know how I should be doing this but am not, please share.
While constructor injection in this scenario appears to be the better solution to the stated problem as it follows The Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
The mention of only needing to access the AppConfig in your views leads me to think that this is more of an XY problem and a cross cutting concern.
It appears that the controllers themselves have no need to use the dependency so stands to reason that there is no need to be injecting them into the controller explicitly just so that the dependency is available to the View.
Consider using an action filter that can resolve the dependency and make it available to the View via the same ViewBag as the request goes through the pipeline.
public class AccessesAppConfigAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var resolver = DependencyResolver.Current;
var appConfig = (IApplicationConfigurationSection)resolver.GetService(typeof(IApplicationConfigurationSection));
filterContext.Controller.ViewBag.AppConfig = appConfig;
}
}
This now makes the required information available to the views with out tight coupling of the controllers that may have a use for it. Removing the need to inject the dependency into derived classes.
Either via adorning Controller/Action with the filter attribute
[AccessesAppConfig] //available to all its actions
public class HomeController : Controller {
//[AccessesAppConfig] //Use directly if want to isolate to single action/view
public ActionResult Index() {
//...
return View();
}
}
or globally for all requests.
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new AccessesAppConfigAttribute());
}
}
At this point it really does not matter which IoC container is used. Once the dependency resolver has been configured, Views should have access to the required information in the ViewBag
Does it make sense to create another layer over the EF6 - Repository/UnitOfWork ?
In our custom repository we can add specific queries like GetTopXXX, GetLastUpdated, etc.
Bu we can do the same in Business Logic with LINQ on DBContext.
I would highly recommend to use a repository to separate the logic that retrieves the data in your situation.
Using the Repository pattern, very briefly, you will implement all your queries such as add, edit, update defined in your interface. And the way which you interact with the database is using Entity Framework.
public interface IProductRepository
{
void Add(Product product);
}
public class ProductRepository : IProductRepository
{
private readonly DbContenxt _dbContext;
public ProductRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Add(Product product)
{
var product = new Product() { Name = "Test" };
_dbContext.Add(product);
_dbContext.SaveChanges();
}
}
I've been dealing with this issue for a while, and still can't seem to find a solution. I have several repositories which wrap an EF 4 ObjectContext. An example is below:
public class HGGameRepository : IGameRepository, IDisposable
{
private readonly HGEntities _context;
public HGGameRepository(HGEntities context)
{
this._context = context;
}
// methods
public void SaveGame(Game game)
{
if (game.GameID > 0)
{
_context.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Modified);
}
else
{
_context.Games.AddObject(game);
}
_context.SaveChanges();
}
public void Dispose()
{
if (this._context != null)
{
this._context.Dispose();
}
}
}
And I have the following NinjectModule:
public class DIModule : NinjectModule
{
public override void Load()
{
this.Bind<HGEntities>().ToSelf();
this.Bind<IArticleRepository>().To<HGArticleRepository>();
this.Bind<IGameRepository>().To<HGGameRepository>();
this.Bind<INewsRepository>().To<HGNewsRepository>();
this.Bind<ErrorController>().ToSelf();
}
}
Since I'm using the MVC 2 extension, these bindings default to InRequestScope().
My problem is that the ObjectContext isn't being handled properly. I get what's described here: https://stackoverflow.com/a/5275849/399584 Specifically, I get an InvalidOperationException that states:
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
This happens every time I try to update an Entity.
If I set my repos to bind InSingletonScope() it works, but seems like a bad idea.
What am I doing wrong?
EDIT: For clarity, I have just one ObjectContext that I want to share with all my repos per request.
You have to specify InRequestScope() in your module. Based on this article the default to transient, which is why you are getting more than one context.
public class DIModule : NinjectModule
{
public override void Load()
{
this.Bind<HGEntities>().ToSelf().InRequestScope();
this.Bind<IArticleRepository>().To<HGArticleRepository>().InRequestScope();
this.Bind<IGameRepository>().To<HGGameRepository>().InRequestScope();
this.Bind<INewsRepository>().To<HGNewsRepository>().InRequestScope();
this.Bind<ErrorController>().ToSelf().InRequestScope();
}
}
Also did you add ninject to your project via nuget package manager or the old fashion way?
Im having a little bit of a problem trying to figure out how to do the following. My apologies if thhe following seems idiotic, just new to Castle.Windsor.
Right, In my application repositories should point to diferent dbs. They all share a abstract class (Db methods abstraction) but there is no correlation between them.
So I have something like this:
public class UserService : IUserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository) { _repository = repository; }
...
}
public class UserRepository : Mongo, IUserRepository
{
public UserRepository(DatabaseHosts.Users UsersHost) : base(UsersHost) { }
...
}
All configuration settings are strongly typed and so far I am calling a Installer for the Settings Service before i call Install on the rest.
My question would be: Do i have to register services and Respositories or there is something im missing?
I think, We could allow access to the DbHost property from the Service, but i rather like not.
We also have providers to external systems which might need some sort of initialization.
So far i have soemthing like this:
public class ServicesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IUserService>()
.ImplementedBy<IUserService>()
.LifeStyle.Singleton);
}
}
Ta
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IUserService>()
.ImplementedBy<UserService>()
.LifeStyle.Singleton);
}
you have to register the concrete service "UserService" to the interface in order to allow the container to determine which concrete to resolve.
We have a class Event (it's actually named differently, but I'm just making abstraction):
public class Event
{
public string Name { get; set; }
public string Description { get; set; }
public EventType EventType { get; set; }
}
We need to build an instance of a Message class with this object, but depending on the EventType, we use a different builder:
switch (event.EventType)
{
case EventType.First:
message = FirstMessageBuilder.Build(event);
break;
case EventType.Second:
message = SecondMessageBuilder.Build(event);
break;
}
Do you think this is acceptable, or should we take the following approach:
Make an abstract class:
public class Event
{
public string Name { get; set; }
public string Description { get; set; }
public abstract Message BuildMessage();
}
Then derive two classes: class FirstMessage and class SecondMessage and make the domain objects responsible for building the message.
I hope it isn't too abstract. The bottom line is we need to transform one class to another. A simple mapper won't do, because there are properties with XML content and such (due to a legacy application making the events). Just accept what we're trying to do here.
The real question is: can a domain object be responsible for such a transformation, or would you not recommend it? I would avoid the ugly switch statement, but add complexity somewhere else.
Whilst I agree with Thomas, you might want to look at the following design patterns to see if they help you:
Vistor Pattern
Double-Dispatch Pattern
Builder Pattern
Strictly speaking, a domain object shouldn't be responsible for anything other than representing the domain. "Changing type" is clearly a technical issue and should be done by some kind of service class, to maintain a clear separation of concerns...
In order to gain the readability of
var message = eventInstance.AsMessage();
as well following the single responsibility principle, you could define AsMessage() as an extension method of the event type.
There are few possible solutions. To use abstract factory:
public interface IMessageFactory
{
Message Create();
}
public class FirstMessageFactory : IMessageFactory
{
public Message Create()
{
//...
}
}
public class SomeService
{
private readonly IMessageFactory _factory;
public SomeService(IMessageFactory factory)
{
_factory = factory;
}
public void DoSomething()
{
var message = _factory.Create();
//...
}
}
Now you can wire IoC container to right factory for requested service.
To use Assembler which makes the transformation:
public interface IAssembler<TSource, TDestination>
{
TDestination Transform(TSource source);
}
This is quite similar to factory pattern, but if you are dependent on EventType, its possible to do it like:
public interface IAssembler<TEventType>
{
object Transform(object source);
}
I would encapsulate the logic into a separate Factory/Builder class, and use an extension method on Event to call the builder.
This would give you the best of both worlds.