0

I have a project on Github that I am trying to develop that shows how to use best practices in a practical way. However I am having problems with the concepts. When I do, I go right back to basics and try a simple example. To see the project follow this link:

https://github.com/franasm/Store.git

The working branch has DI/IOC fully working. The broken branch is what happened when I tried to add a simple business layer. So I went back to basics.

I created a bog standard simple MVC4 application. I then added EF5 with a single table (the product table from the project above).

I decided to add a business layer without any DI/IOC or any fancy stuff. But the concept just confuses me.

All I want to do in this example, is make a class that extends the product class, add a property called TaxAmt, and add a method to calculate the TaxAmt when the class is instantiated.

I tried a variety of ways but get all kinds of errors. From stack overflow execptions, to instance not set exceptions. Most of the time, the thing just doesn't display a value because the Product.Price field is not initialised.

I also find that my BL is in the wrong place:

I have my model,
then my BL,
then my controller.

Fine for this small example. But because the closest to a working example I can get is to create a partial class of the already existing class generated by EF, when I split this out to use DI/IOC the BL is going to be on the wrong side of the interfaces because it will be a part of the Model class (partial class).

I would like to have my layers clearly separated like:
EF Model class,
Interface,
Repo,
BL,
Controller,
ViewModels,
Views.

Because the Repo is responsible for the crud operations. The BL should build on this. After the product details (one of which is price) has been read, the BL can then take this information, do its tax calculation, and then the controller can use this.

Im not sure if my thinking is correct on this.

For the most part I do strongly disagree that the BL should be part of the model. But even if this were to be the case for my contrived example as described above. I still cant get it to work. I would however be looking for a solution to this that would look toward inheriting the model class, extending it, then using it alongside the repo. But this leads me in circles again. The crud gets done by the repo layer, which does not have access to the BL, so how does the BL get initialised in order to do the tax calc. Am I not doubling up on objects, a POCO for each model instance, then also a BL instance of the same object.

Im really confused...

Essentially, I have not included code because all I literally done was make a simple table, a simple mvc project, added EF5 model, wired it all up to do the crud operations and ensure it was working. Then attempted to add a BL as described. A single class in a BL folder that either was defined as a partial class of the model (not ideal), or inherited the model class directly (also not sure if this is cool). Ideally I would like to be able to use DI, to inject my repo into my BL, and then my BL into my controller.

If anyone knows how to do this, can you please provide me with an answer, either by providing step by step instructions (and preferably some sample code) or an explanation of how to go about this process and why I am getting so confused.

Thanks in advance for any help.

Francis Rodgers
  • 4,565
  • 8
  • 46
  • 65

1 Answers1

0

So the best way I have seen to create an MVC application with a business layer and an EF layer is to have a 3-tier layout.

We have the data project, which is likely your EF project (could also be SSDT or something similar), then a "service" layer (could actually be a web service, but could also just be regular class output DLL). I also sometimes call this my "agent" layer. The classes here host the models, and transform the models from EF code to those models. Here is an example of that using LINQ:

public static BlogModel GetBlog(string ID)
    {
        Blog b;
        using (Entities cm = new Entities())
        {
            b = cm.Blogs.Where(blog => blog.ID == ID).FirstOrDefault();
        }

        if (b != null)
            return GetBlog(b);

        return null;
    }

So this method will get a Blog object from the database using EF and LINQ to SQL. Now, to turn that into the model:

public static BlogModel GetBlog(Blog blog)
    {
        return new BlogModel()
        {
            Title = blog.Title,
            Enabled = blog.Enabled
        };
    }

This of course also uses a BlogModel object with a string Title and bool Enabled. Just as examples.

So now you have two methods in your business layer that returns a model. You can now call this in your controller like so:

    [Route("/Blogs/{id}", RouteName = "Blogs")]
        public ActionResult ViewBlogs(string id)
        {
            BlogModel m = BusinessNamespace.BlogClass.GetBlog(id);
            return View("Blogs", m);
        }

Now, assuming you have a Blogs.cshtml view with the correct model set up, you should be good to go.

Hope that helps some.

DorkyMork
  • 66
  • 4
  • Perhaps I am not fully understanding...The middle block of code I would refer to as the model. The first block of code I would consider my repository. The last block is as you said the controller. The first two confuse me because its not clear which comes first, the model or the repo. The way you explain it here, it seems as though the repo comes first. If so, then where does it get the structure of the tables. Is there a EF class defined first also by the same name. In this case, the middle block of code could become the BL but then with 3 blocks of code all named the same, it gets confusing. – Francis Rodgers May 23 '14 at 19:01
  • Yes, this is using EF (you understand more than you give yourself credit for), and for some reason (perhaps it was the hour), I thought this was clear. I can see now it wasn't. Sorry about that. – DorkyMork May 30 '14 at 19:52