I want to achieve two goals:
I want my model to be loaded every time from the DB when it's in a life-cycle (for every request there will be just one request to the DB)
I want my model to be attached dynamically to the page and that wicket will do all this oreable binding for me
In order to achieve these two goals I came to a conclusion that I need to use both CompoundPropertyModel and LoadableDetachableModel.
Does anyone know if this is a good approach?
Should I do new CompoundPropertyModel(myLoadableDetachableModel)?
Yes, you are right, it is possible to use
new CompoundPropertyModel<T>(new LoadableDetachableModel<T> { ... })
or use static creation (it does the same):
CompoundPropertyModel.of(new LoadableDetachableModel<T> { ... })
that has both features of compound model and lazy detachable model. Also detaching works correctly, when it CompoudPropertyModel is detached it also proxies detaching to inner model that is used as the model object in this case.
I use it in many cases and it works fine.
EXPLANATION:
See how looks CompoundPropertyModel class (I'm speaking about Wicket 1.6 right now):
public class CompoundPropertyModel<T> extends ChainingModel<T>
This mean, CompoundPropertyModel adds the property expression behavior to the ChainingModel.
ChainingModel has the following field 'target' and the constructor to set it.
private Object target;
public ChainingModel(final Object modelObject)
{
...
target = modelObject;
}
This take the 'target' reference to tho object or model.
When you call getObject() it checks the target and proxies the functionality if the target is a subclass of IModel:
public T getObject()
{
if (target instanceof IModel)
{
return ((IModel<T>)target).getObject();
}
return (T)target;
}
The similar functionality is implemented for setObject(T), that also sets the target or proxies it if the target is a subclass of IModel
public void setObject(T object)
{
if (target instanceof IModel)
{
((IModel<T>)target).setObject(object);
}
else
{
target = object;
}
}
The same way is used to detach object, however it check if the target (model object) is detachable, in other words if the target is a subclass if IDetachable, that any of IModel really is.
public void detach()
{
// Detach nested object if it's a detachable
if (target instanceof IDetachable)
{
((IDetachable)target).detach();
}
}
Related
I'm used to working the database connections where you connect/open/close as fast as possible in each method. I'm now working with the Entity Framework and so my methods all do this type of thing:
using (var context = new FooEntities()) {
// linq to sql query here
}
I've been told that with Entity Framework I can actually have that context variable be a class level variable and not have to instantiate it in each method. Is that really the case, or should I continue this pattern in each method?
I'm using version 5.0.0 of the framework if that makes a difference.
It depends on how you are expecting it to act. The only reason you'd want it to stick around is if you wanted to use the caching feature of DbContext across multiple method calls. But since its pulling connections from the Pool anyway, disposing of a DbContext shouldn't really impact performance when creating a new one.
For me personally, I create the context as close as possible and kill it as soon as possible. Thus, the Get calls should use AsNoTracking() to speed up the calls a lot if you don't care about trying to update them later. You could also create a DbContextFactory so each class could control that interaction as it sees fit. (i.e. Method A always creates a new one, but Methods B and C could share if either one called first). Though, that could cause its own issues down the road, but then you can opt into those conditions.
You can have Context as a property of a class, but you have to consider how to control the disposing of the Context. For example:
public class UnitOfWork:IDisposable
{
public DbContext Context { get; set; }
public UnitOfWork()
{
Context = null; //initialize context here
}
public void DoWorkWithContext1()
{
//anything you need
}
public void DoWorkWithContext2()
{
//anything you need
}
public void Dispose()
{
if (Context != null)
Context.Dispose();
}
}
Then you'll use the class in this way:
using (var unit= new UnitOfWork())
{
unit.DoWorkWithContext1();
unit.DoWorkWithContext2();
}
DISCLAIMER: Since we are all familiar with it, i will be using contoso university design to explain my question. Also, i am using EF core and .net core 2.0 on a mvc code first design.
I am developing a very generic RESTful API that works on any model. It has one method for each of create, read, update and delete operation in only one controller, the route of this is
[Route("/api/{resource}")]
Resource is the entity that the client wants to work with, for example if someone wants to get all Courses using the api he has to do a GET request on http://www.example.com/api/course/ or http://www.example.com/api/course/2 to get one by id and the following code will do the job.
[HttpGet("{id:int:min(1)?}")]
public IActionResult Read([FromRoute] string resource, [FromRoute] int? id)
{
//find resourse in models
IEntityType entityType = _context.Model
.GetEntityTypes()
.FirstOrDefault(x => x.Name.EndsWith($".{resource}", StringComparison.OrdinalIgnoreCase));
if (entityType == null) return NotFound(resource);
Type type = entityType.ClrType;
if (id == null)//select all from table
{
var entityRows = context.GetType().GetMethod("Set").MakeGenericMethod(type).Invoke(context, null);
if (entityRows == null)
return NoContent();
//TODO: load references (1)
return Ok(entityRows);
}
else //select by id
{
var entityRow = _context.Find(type, id);
if (entityRow == null)
return NoContent();
//TODO: load references (2)
return Ok(entityRows);
}
}
This small piece of code will do the magic with one small exception, intermediate collections will not be loaded. Given our example, the fetched course or courses will have no info for CourseInstructor (the intermediate collection in between Course and Person). I am trying to find a way to Eager load the navigation properties only if it is a collection; or by any other condition that will ensure that only many-to-many relationships are loaded.
For //TODO: load reference (2) i could use
_context.Entry(entityRow).Collection("CourseInsructor").Load();
On runtime if i could find all the navigation properties (filtered by spoken condition) and foreach of them i did Load(), i should get the desired result. My problem is when i get all (when id is null) the entityRows is type 'InternalDbSet' which is an unknown model.
So for the two TODOs i need some help on doing the following steps
1: find navigation properties of many-to-many relationships only
2: load them
Any suggestions?
In general, this seems like a very bad idea to me. While the CRUD stuff is going to be identical for most resources, there will be variances (as you've now run into). There's also something to be said for having a self-documenting API: with individual controllers, you know which resources can be accessed by nature of having a controller associated with that resource. With they way you're doing it, it's a complete black box. This also will of course effect any sort of actual generated API documentation. For example, if you were to include Swagger in your project, it would not be able to determine what you're doing here. Finally, you're now having to use reflection for everything, which will effect your performance.
What I would suggest instead is creating a base abstract controller and then creating a controller for each unique resource that inherits from that, for example:
public abstract class BaseController<TEntity> : Controller
where TEntity : class, new()
{
protected readonly MyContext _context;
public BaseController(MyContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
...
[HttpGet("create")]
public IActionResult Create()
{
var model = new TEntity();
return View(model);
}
[HttpPost("create")]
public async Task<IActionResult> Create(TEntity model)
{
if (ModelState.IsValid)
{
_context.Add(model);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(model);
}
...
}
I just wanted to give a quick example, but you'd build out all the rest of the CRUD methods in the same fashion, generically using TEntity. Then, for each actual resource, you simply do:
public class WidgetController : BaseController<Widget>
{
public WidgetController(MyContext context)
: base(context)
{
}
}
No duplication of code, but you've now got an actual real controller backing the resource, aiding both the innate and possibly explicit documentation of your API. And, no reflection anywhere.
Then, to solve problems like what you have here, you can add hooks to your base controller: essentially just virtual methods that are utilized in your base controller's CRUD actions and do nothing or just default things. However, you can then override these in your derived controllers to stub in additional functionality. For example, you can add something like:
public virtual IQueryable<TEntity> GetQueryable()
=> _context.Set<TEntity>();
Then, in your derived controller, you can do something like:
public class CourseController : BaseController<Course>
{
...
public override IQueryable<Course> GetQueryable()
=> base.GetQueryable().Include(x => x.CourseInstructors).ThenInclude(x => x.Instructor);
So, for example, you'd make your BaseController.Index action, perhaps, utilize GetQueryable() to get the list of entities to display. Simply by overriding this on the derived class, you can alter what happens based on the context of a particular type of resource.
With Autofac, what is the proper way to register types or declare dependencies for this type of circular graph?
public interface IComponent
{
void DoSomething();
}
public class AComponent: IComponent
{
...
}
public class BComponent: IComponent
{
...
}
public class CompositeComponent: IComponent
{
public CompositeComponent(IEnumerable<IComponent> components)
{
this.components = components;
}
public void DoSomething()
{
foreach(var component in components)
component.DoSomething();
}
}
The end goal would be that CompositeComponent be the default registration of IComponent and simply pass down calls to all other implementations.
I am gathering that the intent of the question is that you have some implementations of IComponent and you have some sort of CompositeComponent that also implements IComponent. CompositeComponent needs all of the registered IComponent instances except itself otherwise it creates a circular dependency.
This whole thing overlaps pretty heavily with one of our FAQs: "How do I pick a service implementation by context?"
You have some options. In order of my personal recommendation:
Option 1: Redesign the Interfaces
There are actually two concepts going on here - the notion of an individual handler and the notion of a thing that aggregates a set of individual handlers.
Using less generic terms, you might have an IMessageHandler interface and then something that passes a message through the set of all IMessageHandler implementations, but that thing that aggregates the handlers and deals with errors and ensuring the message is handled only by the right handler and all that... that isn't, itself, also a message handler. It's a message processor. So you'd actually have two different interfaces, even if the methods on the interface look the same - IMessageHandler and IMessageProcessor.
Back in your generic component terms, that'd mean you have IComponent like you do now, but you'd also add an IComponentManager interface. CompositeComponent would change to implement that.
public interface IComponentManager
{
void DoSomething();
}
public class ComponentManager : IComponentManager
{
public ComponentManager(IEnumerable<IComponent> components)
{
this.components = components;
}
public void DoSomething()
{
foreach(var component in components)
component.DoSomething();
}
}
Option 2: Use Keyed Services
If you won't (or can't) redesign, you can "flag" which registrations should contribute to the composite by using service keys. When you register the composite, don't use a key... but do specify that the parameter you want for the constructor should resolve from the keyed contributors.
builder.RegisterType<AComponent>()
.Keyed<IComponent>("contributor");
builder.RegisterType<BComponent>()
.Keyed<IComponent>("contributor");
builder.RegisterType<CompositeComponent>()
.As<IComponent>()
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.Name == "components",
(pi, ctx) => ctx.ResolveKeyed<IEnumerable<IComponent>>("contributor")));
When you resolve IComponent without providing a key, you'll get the CompositeComponent since it's the only one that was registered that way.
Option 3: Use Lambdas
If you know up front the set of components that should go into the composite, you could just build that up in a lambda and not over-DI the whole thing.
builder.Register(ctx =>
{
var components = new IComponent[]
{
new AComponent(),
new BComponent()
};
return new CompositeComponent(components);
}).As<IComponent>();
It's more manual, but it's also very clear. You could resolve individual constructor parameters for AComponent and BComponent using the ctx lambda parameter if needed.
I have a singleton IObservable that returns the results of a Linq query. I have another class that listens to the IObservable to structure a message. That class is Exported through MEF, and I can import it and get asynchronous results from the Linq query.
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes. I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable, but this doesn't happen.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification. I'd appreciate any help.
Below are the singleton and the exported class. I've left out some pieces of code that can be inferred, like the PropertyChanged event handlers and such. Suffice to say, that does work when the underlying Session data changes. The singleton raises a change event for UsersInCurrentSystem, but there is never any request for a new IObservable from the UsersInCurrentSystem property.
public class SingletonObserver: INotifyPropertyChanged
{
private static readonly SingletonObserver _instance = new SingletonObserver();
static SingletonObserver() { }
private SingletonObserver()
{
Session.ObserveProperty(xx => xx.CurrentSystem, true)
.Subscribe(x =>
{
this.RaisePropertyChanged(() => this.UsersInCurrentSystem);
});
}
public static SingletonObserverInstance { get { return _instance; } }
public IObservable<User> UsersInCurrentSystem
{
get
{
var x = from user in Session.CurrentSystem.Users
select user;
return x.ToObservable();
}
}
}
[Export]
public class UserStatus : INotifyPropertyChanged
{
private string _data = string.Empty;
public UserStatus
{
SingletonObserver.Instance.UsersInCurrentSystem.Subscribe(sender =>
{
//set _data according to information in sender
//raise PropertyChanged for Data
}
}
public string Data
{
get { return _data; } }
}
}
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes.
By default MEF will only compose parts once. When a part has been composed, the same instance will be supplied to all imports. The part will not be recreated unless you explicitly do so.
In your case, if the data of a part change, even if it implements INotifyPropertyChanged, MEF will not create a new one, and you don't need to anyway.
I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable
No.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification.
Property notification allows you to react to a change in the property and has no direct effect on MEF. As for the container's lifetime, it will remain active until it is disposed. While it is still active, the container will keep references to it's compose parts. It's actually a little more complex than that, as parts can have different CreationPolicy that affects how MEF holds the part, I refer you to the following page: Parts Lifetime for more information.
MEF does allow for something called Recomposition. You can set it likewise:
[Import(AllowRecomposition=true)]
What this does tough is allow MEF to recompose parts when new parts are available or existing parts aren't available anymore. From what I understand it isn't what you are referring to in your question.
I'm having problems with the NetBeans Nodes API.
I have this line of code:
Node n = (new MyNode(X)).getChildren().getNodeAt(Y);
The call to new MyNode(X) with the same X always initializes a MyNode the same way, independent of the context.
When I place it by itself (say, in an menu action), it successfully gets the Yth child, but if I put it in an event where other Node/Children stuff happens, it returns null.
MyNode's Children implementation is a trivial subclass of Children.Keys, which is approximately:
// Node
import org.openide.nodes.AbstractNode;
class MyNode extends AbstractNode {
MyNode(MyKey key) {
super(new MyNodeChildren(key));
}
}
// Children
import java.util.Collections;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
public class MyNodeChildren extends Children.Keys<MyKey> {
MyKey parentKey;
MyNodeChildren(MyKey parentKey) {
super(true); // use lazy behavior
this.parentKey = parentKey;
}
#Override
protected Node[] createNodes(MyKey key) {
return new Node[] {new MyNode(key)};
}
#Override
protected void addNotify() {
setKeys(this.parentKey.getChildrenKeys());
}
#Override
protected void removeNotify() {
setKeys(Collections.EMPTY_SET);
}
}
// MyKey is trivial.
I assume this has something to do with the lazy behavior of Children.Keys. I have the sources for the API, and I've tried stepping through it, but they're so confusing that I haven't figured anything out yet.
NetBeans IDE 7.0.1 (Build 201107282000) with up-to-date plugins.
Edit: More details
The line with the weird behavior is inside a handler for an ExplorerManager selected-nodes property change. The weird thing is that it still doesn't work when the MyNode instance isn't in the heirarchy that the ExplorerManager is using (it's not even the same class as the nodes in the ExplorerManager), and isn't being used for anything else.
Accessing the nodes instead of the underlying model is actually necessary for my use case (I need to do stuff with the PropertySets), the MyNode example is just a simpler case that still has the problem.
It is recommended to use org.openide.nodes.ChildFactory to create child nodes unless you have a specific need to use one of the Children APIs. But for the common cases the ChildFactory is sufficient.
One thing to keep in mind when using the Nodes API is that it is only a presentation layer that wraps your model and used in conjunction with the Explorer API makes it available to the various view components in the NetBeans platform such as org.openide.explorer.view.BeanTreeView.
Using a model called MyModel which may look something like:
public class MyModel {
private String title;
private List<MyChild> children;
public MyModel(List<MyChild> children) {
this.children = children;
}
public String getTitle() {
return title;
}
public List<MyChild> getChildren() {
return Collections.unmodifiableList(children);
}
}
You can create a ChildFactory<MyModel> that will be responsible for creating your nodes:
public class MyChildFactory extends ChildFactory<MyModel> {
private List<MyModel> myModels;
public MyChildFactory(List<MyModel> myModels) {
this.myModels = myModels;
}
protected boolean createKeys(List<MyModel> toPopulate) {
return toPopulate.addAll(myModels);
}
protected Node createNodeForKey(MyModel myModel) {
return new MyNode(myModel);
}
protected void removeNotify() {
this.myModels= null;
}
}
Then, implementing MyNode which is the presentation layer and wraps MyModel:
public class MyNode extends AbstractNode {
public MyNode(MyModel myModel) {
this(myModel, new InstanceContent());
}
private MyNode(MyModel myModel, InstanceContent content) {
super(Children.create(
new MyChildrenChildFactory(myModel.getChildren()), true),
new AbstractLookup(content)); // add a Lookup
// add myModel to the lookup so you can retrieve it latter
content.add(myModel);
// set the name used in the presentation
setName(myModel.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/icon.png");
}
}
And now the MyChildrenChildFactory which is very similar to MyChildFactory except that it takes a List<MyChild> and in turn creates MyChildNode:
public class MyChildFactory extends ChildFactory<MyChild> {
private List<MyChild> myChildren;
public MyChildFactory(List<MyChild> myChildren) {
this.myChildren = myChildren;
}
protected boolean createKeys(List<MyChild> toPopulate) {
return toPopulate.addAll(myChildren);
}
protected Node createNodeForKey(MyChild myChild) {
return new MyChildNode(myChild);
}
protected void removeNotify() {
this.myChildren = null;
}
}
Then an implementation of MyChildNode which is very similar to MyNode:
public class MyChildNode extends AbstractNode {
public MyChildNode(MyChild myChild) {
// no children and another way to add a Lookup
super(Children.LEAF, Lookups.singleton(myChild));
// set the name used in the presentation
setName(myChild.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/child_icon.png");
}
}
And we will need the children's model, MyChild which is very similar to MyModel:
public class MyChild {
private String title;
public String getTitle() {
return title;
}
}
Finally to put it all to use, for instance with a BeanTreeView which would reside in a TopComponent that implements org.openide.explorer.ExplorerManager.Provider:
// somewhere in your TopComponent's initialization code:
List<MyModel> myModels = ...
// defined as a property in you TC
explorerManager = new ExplorerManager();
// this is the important bit and we're using true
// to tell it to create the children asynchronously
Children children = Children.create(new MyChildFactory(myModels), true);
explorerManager.setRootContext(new AbstractNode(children));
Notice that you don't need to touch the BeanTreeView and in fact it can be any view component that is included in the platform. This is the recommended way to create nodes and as I've stated, the use of nodes is as a presentation layer to be used in the various components that are included in the platform.
If you then need to get a child you can use the ExplorerManager which you can retrieve from the TopComponent using the method ExplorerManager.Provier.getExplorerManager() which was implemented due to the fact that your TopComponent implemented ExplorerManager.Provider and is in fact the way that a view component itself gets the nodes:
ExplorerManager explorerManager = ...
// the AbstractNode from above
Node rootContext = explorerManager.getRootContext();
// the MyNode(s) from above
Children children = rootContext.getChildren().getNodes(true);
// looking up the MyModel that we added to the lookup in the MyNode
MyModel myModel = nodes[0].getLookup().lookup(MyModel.class);
However, you must be aware that using the Children.getNodes(true) method to get your nodes will cause all of your nodes and their children to be created; which weren't created due to the fact that we told the factory that we wanted it to create the children asynchronously. This is not the recommended way to access the data but instead you should keep a reference to the List<MyModel> and use that if at all possible. From the documentation for Children.getNodes(boolean):
...in general if you are trying to get useful data by calling this method, you are probably doing something wrong. Usually you should be asking some underlying model for information, not the nodes for children.
Again, you must remember that the Nodes API is a presentation layer and is used as an adapter between your model and your views.
Where this becomes a powerful technique is when using the same ChildFactory in different and diverse views. You can reuse the above code in many TopComponents without any modifications. You can also use a FilterNode if you need to change only a part of the presentation of a node without having to touch the original node.
Learning the Nodes API is one of the more challenging aspects of learning the NetBeans platform API as you have undoubtedly discovered. Once you have some mastery of this API you will be able to take advantage of much more of the platforms built in capabilities.
Please see the following resources for more information on the Nodes API:
NetBeans Nodes API Tutorial
Great introduction to the Nodes API by Antonio Vieiro
Part 5: Nodes API and Explorer & Property Sheet API by Geertjan Wielenga
JavaDocs for the Nodes API
Timon Veenstra on the NetBeans Platform Developers mailing list solved this for me.
Actions on the explorerManager are guarded to ensure consistency. A
node selection listener on an explorer manager for example cannot
manipulate the same explorer manager while handling the selection
changed event because that would require a read to write upgrade. The
change will be vetoed and die a silent death.
Are you adding the MyNode root node to the explorer manager on
initialization, or somewhere else in a listener?
My problem line is in an ExplorerManager selection change listener. I guess the Children.MUTEX lock is getting set by ExplorerManager and preventing the Children.Keys instance from populating its Nodes...?
Anyways, I moved my Node access into a EventQueue.invokeLater(...), so it executes after the selection changed event finishes, and that fixed it.