I'm playing around with the SimpleRepository provider (with automigrations) in SubSonic 3 and I have an annoying problem:
The only way I can control the string length in my database tables is by adding the SubSonicStringLength or SubSonicLongString attributes to the properties of the objects that need to be persisted.
I don't really want a dependency on SubSonic anywhere except in my repository class, and certainly not in my model objects if I can avoid it.
Are there anyways to get round this or am I stuck using SubSonicStringLength and the other attributes?
Basically the only way around this would be to have a DTO object that you map to/from your SimpleRepository classes inside your repository. You could use a mapping tool like AutoMapper to convert to/from your DTOs to your SimpleRepo objects.
This would isolate your application from SubSonic dependencies outside of your repo but would obviously involve a non trivial amount of work.
Related
I am having a bit of trouble implementing the Repository pattern, due to some confusion.
As far as I can tell now, a Repository should behave like an in-memory collection of objects, so if I do say:
$users = new UserRepository(new UserMapper);
$users->findAll();
The Users repository will load and return an array of User entities. Now I can either use them for just reading data, or can update the data on any particular entity, and invoke a save() method on the Repository that will utilize the Mapper to save the loaded entities back to the data source, with the updates that have been applied.
What I am wondering is if that is a correct understanding.
Should the add() method add an entity directly to the data source, or only to the collection within the Repository?
Likewise for remove(); should this method remove an entity from the data source, or only from the Repository.
The confusion stems from the fact that some implementations I have seen in tutorials have both add()/remove() methods, alongside save()/delete() methods. Is that the correct approach?
I've been developing using DDD techniques for around 6 months now and always use the save and delete methods, the save should persist the data to your persistence layer, the delete should remove from your persistence layer.
Saying the above, there is no reason why it shouldnt add to your collection.
p.s check out the dddinphp Google Group, theres an active community purely for these questions
When doing managed objectmapping with RestKit, using core data, i map using my NSManaged subclasses fe. User.m
And that works fine.
But if i need to do ordinary objectmapping it is not possible to still use the NSManaged Subclass - User.m, as the mapping object.
I then have to create a new object, subclassing NSObject, with the exact same ivars i.e. UserOBJmapping.m
This is kind of a waste, and i wonder if there is a more clever way to do it, so i do not have to create classes that have the same internal structure.
The reason why i have to do this, is that whenever RestKit maps an incoming objectstream to User, it is put directly in the store, and i have situations where i need the data not to be store, but simply be in my cache memory for manipulation.
Just like i do with normal Object Mapping.
I think there properly is a way to do this with managed objects in RestKit but have found no info about it anywhere.
I hope that someone might have a some idea for achieving a more clever solution.!
Thanx
It's a limitation in Core Data. You can't have NSManagedObject instances without a context.
Can RestKit map to a dictionary instead?
I am going to use subsonic 3 in a large enterprise winform application.
what i saw in my personal tests is that subsonic cannot handle complex type references well.
for example if we have an ADDRESS complex type in PERSON object , as far as i saw subsonic just created the PERSON table and is not caring about the Address property of it !
i was wondering how can i solve it ?
Secondly, we have inheritance in our objects, how subsonic can handle it with table-per-subclass strategy?
SubSonic isn't well suited to these scenarios. Regarding complex types you could write a service/repository to handle saving and building these types, but there's no pre-existing way of mapping this to the database.
The same goes for inheritance schemes.
You might want to look at more full-featured O/RM like NHibernate or EF.
I'm facing several problems trying to apply DDD with EF4 (in ASP MVC2 context). Your advaice would be greatly appreciated.
First of all, I started to use POCO because the dependacy on ObjectContext was not very comfortable in many situations.
Going to POCO solved some problems but the experience is not what I was used to with NHibernate.
I would like to know if it's possible to use designer and to generate not only entities but also a Value Objects (ComplexType?). If I mean Value Object is a class with one ctor without any set properties (T4 modification needed ?).
The only way I found to add behavior to anemic entities is to create partial classes that extends those generated by edmx. I'm not satisfied with this approach.
I don't know how to create several repositories with one edmx. For now I'm using a partial classes to group methods for each aggregate. Each group is a repository in fact.
The last question is about IQueryable. Should it be exposed outside the repository ? If I refer to the ble book, the repository should be a unit of execution and shouldn't expose something like IQueryable. What do you think ?
Thanks for your help.
Thomas
It's fine to use POCOs, but note that EntityObject doesn't require an ObjectContext.
Yes, Complex Types are value objects and yes, you can generate them in the designer. Select several properties of an entity, right click, and choose refactor into complex type.
I strongly recommend putting business methods in their own types, not on entities. "Anemic" types can be a problem if you must maintain them, but when they're codegened they're hardly a maintenance problem. Making business logic separate from entity types allows your business rules and your data model to evolve independently. Yes, you must use partial classes if you must mix these concerns, but I don't believe that separating your model and your rules is a bad thing.
I think that repositories should expose IQueryable, but you can make a good case that domain services should not. People often try to build their repositories into domain services, but remember that the repository exists only to abstract away persistence. Concerns like security should be in domain services, and you can make the case that having IQueryable there gives too much power to the consumer.
I think it's OK to expose IQueryable outside of the repository, only because not doing so could be unnecessarily restrictive. If you only expose data via methods like GetPeopleByBirthday and GetPeopleByLastName, what happens when somebody goes to search for a person by last name and birthday? Do you pull in all the people with the last name "Smith" and do a linear search for the birthday you want, or do you create a new method GetPeopleByBirthdayAndLastName? What about the poor hapless fellow who has to implement a QBE form?
Back when the only way to make ad hoc queries against the domain was to generate SQL, the only way to keep yourself safe was to offer just specific methods to retrieve and change data. Now that we have LINQ, though, there's no reason to keep the handcuffs on. Anybody can submit a query and you can execute it safely without concern.
Of course, you could be concerned that a user might be able to view another's data, but that's easy to mitigate because you can restrict what data you give out. For example:
public IQueryable<Content> Content
{
get { return Content.Where(c => c.UserId == this.UserId); }
}
This will make sure that the only Content rows that the user can get are those that have his UserId.
If your concern is the load on the database, you could do things like examine query expressions for table scans (accessing tables without Where clauses or with no indexed columns in the Where clause). Granted, that's non-trivial, and I wouldn't recommend it.
It's been some time since I asked that question and had a chance to do it on my own.
I don't think it's a good practice to expose IQueryable at all outside the DAL layer. It brings more problems that it solves. I'm talking about large MVC applications. First of all the refactorings is harder, many developers user IQueryable instances from the views and after struggle with the fact that when resolving IQueryable the connection was already disposed. Performance problems because all the database is often queried for a given set of resultats and so on.
I rather expose Ienumerable from my repositories and believe me, it saves me many troubles.
This is an embarrassingly basic n-tier question.
I've created a DAL project in VS2008 with subsonic. It's got a widget class, a widgetcollection class, and a widgetcontroller class.
I've created my Business logic project (no I can't put it in the same tier) that references it. Using certain business criteria, it selects a collection of widgets in a function that returns a widgetcollection.
My question is: how does my GUI layer bind the collection to a grid? I know that the widgetcollection is a valid datasource for a datagrid, but how does the GUI layer know what a widget and widgetcollection are? Surely I don't have to reference the DAL from the GUI, that negates the whole point.
Firstly, I dont think this is an embarrasingly basic n-tier question.
It is a very interesting subject and one I attempted to stimulate discussion for in the old Subsonic Forums.
I share your reluctance to expose my GUI layer to the DAL.
My GUI layer only talks to BLL using the vocabulary and topics of my own Entity Model and only returns my own entities or lists or in some cases Data Tables.
My BLL only talks to a MAPping layer which maps Fetches,Saves etc to the appropriate DAL CRUD methods and converts the returned Subsonic types to my Entity types.
In doing this I was suprised at how much of Subsonic I had to duplicate and at times I felt I was going down the wrong road, I am feeling more comfortable with it now, though it still needs refactoring and refining.
For example, finding a flexible, generic means of indicating to my BLL which row(s) I wanted returned in a fetch was a challenge I hadn't expected and I finished up writing a generic queryClass with fluent interface which looks a lot like a Subsonic Select.
FWIW, I think you are headed down the right track, I guess what you have to do though is decide how you want to define those Subsonic types to your GUI.
Rob has an interesting discussion you may be interested in.
(using SubSonic 2.x) In my BLL classes I have a property which gives an object reference to the relevant DAL class. My UI form has a reference to the BLL class, so from the form I can address the DAL properties and methods via .BLL.DAL.xxxx
FWIW, I have never managed to successfully bind a SubSonic collection to a DataGridView. As alternatives, I sometimes use the collections .ToTable() method to create a DataTable and then bind to that, or alternatively I manually bind using .AddRow()
Look at the documentation for IBindingList Interface in MSDN, it has a pretty good sample.
Create, for example, a CustomersList class in your model that uses a Customer class in your BLL. Bind the grid to an instance of the CustomersList class. The presentation layer has no knowledge of the subsonic table classes.
You probably need to use an Interface. You can easily create an interface based off of the Widget in your Dal(right click on the class and create an Interface from the class). Next take the Interface and add it to your Business Logic Layer or a seperate project just for interfaces. Once you have done that you can add a reference to the Interface both in the DAL and in the GUI. This can also help if you ever change your data storage from a Database to XML etc. etc.