I have a ASP.NET MVC3 solution named "SampleProject". I have 4 projects in the solution.
The project names of the solution are
SampleProject.Data (holds entity classes, DAL classes, and filter classes)
SampleProject.Service (something like BLL in standard ERP)
SampleProject.Tests (test project)
SampleProject.Web (holds controllers and views)
I am calling the Service classes from my controllers. The service classes are calling Data classes and data classes are performing the database operations.
I have done create, list and details part. Now I stucked in Edit part. None of the examples (NerdDinner,MVCMusicStore etc) using my architecture. In the provided examples(NerdDinner,MVCMusicStore etc or in ASP.NET website tutorials), they are just using built in UpdateModel method which I don't want to use. I want to manually get the model object from my view and send it to my Data layer for update.
My question is, how can I update the models through different project layer?
I solved the porblem. Here is the code.Just for reference, CResult is a class which contains IsSuccess(bool), Message(string) properties in it.
CResult oCResult;
[HttpPost]
public ActionResult Edit(Restaurant model)
{
try
{
oCResult = restaurantService.Update(model);
if (oCResult.IsSuccess)
{
return RedirectToAction("Index");
}
return View("Error");
}
catch
{
return View();
}
}
The view engine prepares the object (in my case, it is Restaurant type of object) it inherits with new values and send back to controller. this is my understanding.
Related
I build a web app using sails.js and I have few questions about the design of the app:
Should I create controllers for each page, component, or model? I saw in the documentation and at some tutorials that they create controllers for each model. That looks nice but if I have a complex page/component and I want to create view with multi models (and data) it doesn't help me.
Where should I put the business logic part of a component or feature? I read about Serivce but I'm not sure that this is the right place.
To sum up, I saw that in sails the code is arranged like the models (you have model, controller and view for each model) but what if I want to arrange it by features or components or pages?
Thanks!
Basically you should have Controller for each Model (but if you don't need specific controller and it would be empty you don't need to create it). It's just a good practice to have a Controller for each Model.
If you use some part of code in many places and it is not connected with one specified Model it should be Service (like sending emails, notifications, logging, images processing). Read about DRY
Controller should be as simple as possible. It should contain call of Model and Service and callback with rendering output. All business logic should be in Models.
I created some additional 'helper' Models for more complex Models like Users or so to make Classes bit shorter.
To sum up. Core of your application is Model. It's not only responsible for database layer, bur also business layer of your app. Later there is Controller. It gets data from Model and it passes it to Views which is responsible for presentation of data taken from Model.
Answer to First
Sails is for REST API it has nothing to do with view.
you just need to know what MVC is and what REST is....
In one Controller you can invoke multiple models or one model can be invoked in multiple controllers.
In one page you can fetch data from two different API's which may be from different controller or Even they can be of different server.
for Example:
In the page you are getting data directly from ellasticsearchAPI(say esAPI1)
You are getting data from sails API(sAPI1).
You are getting data from other sails API(sAPI2).
Answer to Second
For neatness you should try to keep controller as clean as possible. So for the same sailsJS provide you services. Where you can write Common functionalities which are to be used in multiple controllers.
See the codes for example
Codes
here is the controller:
//TestController
module.exports = {
action1:function(req,res){
Model1.find().exec(function(err,data1){
if(err)
return res.negotiate(err);
res.ok(data1);
});
},
action2:function(req,res){
Model2.find().exec(function(err,data1){
if(err)
return res.negotiate(err);
res.ok(data2);
});
},
action3:function(req,res){
var hash=SomeService.getMeHashCode(req.query.text)
res.ok({hashedData:hash});
}
};
And this is service.
//SomeService.js
module.exports = {
getMeHashCode:function(strinToBeHashed){
var hash=doSomeThingToHash(strinToBeHashed);
return hash;
}
};
I just finish to implement Repository Pattern & Unit of Work using Ninject Dependency Injection into my asp.net web api project.
Im using Entity Framework as my ORM.
I have the following soluction structure (projects):
Web Application (asp.net web api)
Data (DBContext, Repositories)
Interfaces (IRepository, etc)
Model (POCO Classes from DB)
So for example my PersonRepository (Data project):
public class PersonsRepository : EFRepository<Person>, IPersonsRepository
{
public PersonsRepository(DbContext context) : base(context) { }
public IQueryable<Person> GetByAge(int age)
{
return DbSet.FirstOrDefault(ps => ps.age == age);
}
public void Delete(int personId, int age)
{
// Here I want to validate some stuff before deleting
// Business Rules need to be here!!
var attendance = new Attendance {PersonId = personId, Age = age};
Delete(attendance);
}
}
So my question is if its correct to implement all the business logic inside my Repository Methods? and also what is the best way to return a message or validation in case I need to.
Thanks and appreciate any help!
There should be a new layer between Data and Web called Business. Web will reference Business layer only and Business layer will reference Data layer only. So the Business layer before or after calling the Data layer can implement all its validation and business logic.
No, it isn't. The repository implementation belongs to persistence (DAL). Repository is concerned with 'converting' business objects to/from whatever form used to store them into the database. It isn't its responsibility to care about business logic. Business logic stays in the business layer, in the domain.
Business logic is contained by domain objects and services. It never gets outside the business layer, not in UI (controllers) not in DAL (repositories, EF etc).
The repository implementation you're using is incorrect, an anti-pattern, as it defeats the purpose of a repository: to decouple the business layer from the persistence details (EF is an implementation detail). The repository's interface should never expose details like IQueryable or EF entities. It should 'know' only about business objects.
Your solution structure makes little sense to me: all interfaces you're using should be in the layer they belong to(repository interface is part of business layer, that's why it shouldn't know about EF). The Model, based on your description seems to be the persistence model (it should be part of Data).
You want a Business(Domain) layer where Model really means business model. Not to be confused with persistence model(used by EF), view model(used by a View) or the M from MVC (used by Controllers) :) . The M from MVC refers to parts of the business model but it's not the same thing as the business model.
I suggest to take your time and read a bit more about repository pattern and 3-tier architecture and make sure you've understood the concepts and their purpose.
I'm doing an Windows Phone app where I have a WebApi running in Azure.
I'm using the new "Portable Class Library" (http://msdn.microsoft.com/en-us/library/gg597391.aspx) for my "Models" project which is of cause shared between my WebApi project (this is a normale ASp.NET MVC 4 project) and my Windows Phone project.
This works great and the model (POCO) classes are serialized and deserialized just as I want.
Now I want to start storing some of my Models/POCO objects and would like to use EF Code-first for that, but that's kind of a problem as I can't add the EntityFramework assembly to my "Portable Class Library" project, and really I would not like to either as I only need a small part (the attributes) in my Models project.
So, any suggestions to how a approach this the best way?
UPDATE:
Well, it seems like I can actually add the EntityFramework assembly to the project, but that doesn't really help me, as the attributes I need to use lives in System.ComponentModel.DataAnnotations which can't be used on Windows Phone.
Any suggestions still?
Don't use attributes. Use fluent API instead and create separate assembly for persistence (EF) which will reference your model assembly. Persistence assembly will be use used by your WebAPI layer.
I use a modified approach than Mikkel Hempel's, without the need to use pre processing directives.
Create a standard .NET class library, call it Models
Create a partial class representing what you want to be shared
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
For non-portable code (like DataAnnotations), create another partial class and use Metadata
[MetadataTypeAttribute(typeof(Person.Metadata))]
public partial class Person
{
internal sealed class Metadata
{
private Metadata() { } // Metadata classes shouldn't be instantiated
// Add metadata attributes to perform validation
[Required]
[StringLength(60)]
public string Name;
}
}
Create a Portable Class Library, and add the class from step 2 "As Link"
When I need my domain-project across multiple platforms, I usually:
Create the standard .NET-class library project for the domain code
For each platform I create a platform specific class library
For each platform specific class library I add the files from the standard .NET-class library as links (Add existing files -> As link) and hence they're updated automatically when you edit either the linked file or the original file.
When I add a new file to the .NET-class library, I add it as links to the platform specific class libraries.
Platform specific attributes (i.e. Table and ForeignKey which is a part of the DataAnnotations-assembly) can be opted out using the pre-processor tags. Lets say I have a .NET-class library with a class and a Silverlight-project with the linked file, then I can include the .NET-specific attributes by doing:
#if !SILVERLIGHT
[Table("MyEntityFrameworkTable")]
#endif
public class MyCrossPlatformClass
{
// Blah blah blah
}
and only include the DataAnnotations-assembly in the .NET-class library.
I know it's more work than using the Portable Class Library, but you can't opt out attributes in a PCL like in the example above, since you're only allowed to reference shared assemblies (which again DataAnnotations is not).
Using Nerd Dinner as an example:
private NerdDinnerDataContext db = new NerdDinnerDataContext();
public IQueryable<Dinner> FindAllDinners()
{
return db.Dinners;
}
Is it not bad practice to directly expose the entity class Dinner here? I think it is better for the repository to return an IDinner.
So my question is, how can I make the auto-generated entity classes expose my interface?
As far as I know, the only way would be to modify the template from which the code is generated. Another possibility is partial classes. The code generator creates partial classes. You could create another partial class that contains the interface you want. I believe this will work.
Method chaining is the only way I know to build fluent interfaces.
Here's an example in C#:
John john = new JohnBuilder()
.AddSmartCode("c#")
.WithfluentInterface("Please")
.ButHow("Dunno");
Assert.IsNotNull(john);
[Test]
public void Should_Assign_Due_Date_With_7DayTermsVia_Invoice_Builder()
{
DateTime now = DateTime.Now;
IInvoice invoice = new InvoiceBuilder()
.IssuedOn(now)
.WithInvoiceNumber(40)
.WithPaymentTerms(PaymentTerms.SevenDays)
.Generate();
Assert.IsTrue(invoice.DateDue == now.AddDays(7));
}
So how do others create fluent interfaces. How do you create it? What language/platform/technology is needed?
The core idea behind building a fluent interface is one of readability - someone reading the code should be able to understand what is being achieved without having to dig into the implementation to clarify details.
In modern OO languages such as C#, VB.NET and Java, method chaining is one way that this is achieved, but it's not the only technique - two others are factory classes and named parameters.
Note also that these techniques are not mutually exclusive - the goal is to maximize readabilty of the code, not purity of approach.
Method Chaining
The key insight behind method chaining is to never have a method that returns void, but to always return some object, or more often, some interface, that allows for further calls to be made.
You don't need to necessarily return the same object on which the method was called - that is, you don't always need to "return this;".
One useful design technique is to create an inner class - I always suffix these with "Expression" - that exposes the fluent API, allowing for configuration of another class.
This has two advantages - it keeps the fluent API in one place, isolated from the main functionality of the class, and (because it's an inner class) it can tinker with the innards of the main class in ways that other classes cannot.
You may want to use a series of interfaces, to control which methods are available to the developer at a given point in time.
Factory Classes
Sometimes you want to build up a series of related objects - examples include the NHibernate Criteria API, Rhino.Mocks expectation constraints and NUnit 2.4's new syntax.
In both of these cases, you have the actual objects you are storing, but to make them easier to create there are factory classes providing static methods to manufacture the instances you require.
For example, in NUnit 2.4 you can write:
Assert.That( result, Is.EqualTo(4));
The "Is" class is a static class full of factory methods that create constraints for evaluation by NUnit.
In fact, to allow for rounding errors and other imprecision of floating point numbers, you can specify a precision for the test:
Assert.That( result, Is.EqualTo(4.0).Within(0.01));
(Advance apologies - my syntax may be off.)
Named Parameters
In languages that support them (including Smalltalk, and C# 4.0) named parameters provide a way to include additional "syntax" in a method call, improving readability.
Consider a hypothetical Save() method that takes a file name, and permissions to apply to the file after saving:
myDocument.Save("sampleFile.txt", FilePermissions.ReadOnly);
with named parameters, this method could look like this:
myDocument.Save(file:"SampleFile.txt", permissions:FilePermissions.ReadOnly);
or, more fluently:
myDocument.Save(toFile:"SampleFile.txt", withPermissions:FilePermissions.ReadOnly);
You can create a fluent interface in any version of .NET or any other language that is Object Oriented. All you need to do is create an object whose methods always return the object itself.
For example in C#:
public class JohnBuilder
{
public JohnBuilder AddSmartCode(string s)
{
// do something
return this;
}
public JohnBuilder WithfluentInterface(string s)
{
// do something
return this;
}
public JohnBuilder ButHow(string s)
{
// do something
return this;
}
}
Usage:
John = new JohnBuilder()
.AddSmartCode("c#")
.WithfluentInterface("Please")
.ButHow("Dunno");
AFAIK, the term fluent interface does not specify a specific technology or framework, but rather a design pattern. Wikipedia does have an extensive example of fluent interfaces in C♯.
In a simple setter method, you do not return void but this. That way, you can chain all of the statements on that object which behave like that. Here is a quick example based on your original question:
public class JohnBuilder
{
private IList<string> languages = new List<string>();
private IList<string> fluentInterfaces = new List<string>();
private string butHow = string.Empty;
public JohnBuilder AddSmartCode(string language)
{
this.languages.Add(language);
return this;
}
public JohnBuilder WithFluentInterface(string fluentInterface)
{
this.fluentInterfaces.Add(fluentInterface);
return this;
}
public JohnBuilder ButHow(string butHow)
{
this.butHow = butHow;
return this;
}
}
public static class MyProgram
{
public static void Main(string[] args)
{
JohnBuilder johnBuilder = new JohnBuilder().AddSmartCode("c#").WithFluentInterface("Please").ButHow("Dunno");
}
}
Sometime ago I had the same doubts you are having now. I've done some research and now I'm writing a series of blog posts about techinics of designing a fluent interface.
Check it out at:
Guidelines to Fluent Interface design in C# part 1
I have a section there about Chaining X Nesting that can be interesting to you.
In the following posts I will talk about it in a deeper way.
Best regards,
André Vianna
Fluent interface is achieved in object oriented programming by always returning from your methods the same interface that contains the method. Consequently you can achieve this effect in java, javascript and your other favorite object oriented languages, regardless of version.
I have found this technique easiest to accomplish through the use of interfaces:
public interface IFoo
{
IFoo SetBar(string s);
IFoo DoStuff();
IFoo SetColor(Color c);
}
In this way, any concrete class that implements the interface, gets the fluent method chaining capabilities. FWIW.. I wrote the above code in C# 1.1
You will find this technique littered throughout the jQuery API
A couple of things come to mind that are possible in .Net 3.5/C# 3.0:
If an object doesn't implement a fluent interface, you could use Extension Methods to chain your calls.
You might be able to use the object initialization to simulate fluent, but this only works at instantiation time and would only work for single argument methods (where the property is only a setter). This seems hackish to me, but the there it is.
Personally, I don't see anything wrong with using function chaining if you are implementing a builder object. If the builder object has chaining methods, it keeps the object you are creating clean. Just a thought.
This is how I've built my so called fluent interfaces or my only forary into it
Tokenizer<Bid> tkn = new Tokenizer<Bid>();
tkn.Add(Token.LambdaToken<Bid>("<YourFullName>", b => Util.CurrentUser.FullName))
.Add(Token.LambdaToken<Bid>("<WalkthroughDate>",
b => b.WalkThroughDate.ToShortDateString()))
.Add(Token.LambdaToken<Bid>("<ContactFullName>", b => b.Contact.FullName))
.Cache("Bid")
.SetPattern(#"<\w+>");
My example required .net 3.5 but that's only cause of my lambda's. As Brad pointed out you can do this in any version of .net. Although I think lambda's make for more interesting possibilities such as this.
======
Some other good examples are nHibernate's Criteria API, there is also a fluent nhibernate extension for configuring nhibernate but I've never used it
Dynamic keyword in C# 4.0 will make it possible to write dynamic style builders. Take a look at following article about JSON object construction.