C# Unity Container Constructor Injection transient lifetime manager same instance served - c#

Problem: I have some XSD generated models that are complex and I wanted to let Unity construct them. There are many nestings and arrays of classes within classes and I'd rather not new them up.
That given if I do that and use constructor injection, it seems I'm not getting a new model every time I use the generation class. My populated list contains records where all records reference the same instance.
This example simplifies the issue:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Unity;
namespace sandbox
{
public class Test
{
private GetTestRec _getTestRec;
public Test(GetTestRec getTestRec)
{
_getTestRec = getTestRec;
}
public void RunMe()
{
var mylist = new List<TestModel>();
var InList = new List<StructIn>();
InList.Add(new StructIn() { Name = "asd", Amount = 5.55F });
InList.Add(new StructIn() { Name = "lkj", Amount = 1.00F });
foreach (var item in InList)
{
mylist.Add(_getTestRec.Get(item));
}
foreach (var item in mylist)
{
Console.WriteLine($"{item.Name} {item.Amount}" );
}
}
}
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
//_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
public class TestModel
{
public TestModel()
{ }
public string Name { get; set; }
public float Amount { get; set; }
}
public struct StructIn
{
public string Name;
public float Amount;
}
}
In the above code the TestModel is being resolved explicitly. If I resolve the GetTestRec and execute RunMe()...
var testThis = UnityConfig.Container.Resolve<Test>();
testThis.RunMe();
You can see that it correctly generates two instances of the TestModel and adds them to the list
asd 5.55
lkj 1
But if I comment out the explicit resolve and instead inject the TestModel through the constructor...
public class GetTestRec
{
private TestModel _testModel;
public GetTestRec(TestModel testModel)
{
_testModel = testModel;
}
public TestModel Get(StructIn structIn)
{
//_testModel = UnityConfig.Container.Resolve<TestModel>();
_testModel.Name = structIn.Name;
_testModel.Amount = structIn.Amount;
return _testModel;
}
}
You can see that it's only using one instance of the TestClass and all records in the list point to the same instance
lkj 1
lkj 1
How do I use the constructor injection and get a new instance every time? The default transient lifetime says it gets a new instance with every resolve and if I call resolve then I do get a new instance. But, using the constructor I don't believe resolve is called as it's already been previously resolved.
What is the best direction here? Is a Factory pattern with Unity where I should be looking?

Assuming you are looking to return new model on every call to TestModel Get (essentially replacing new TestModel with some sort of DI friendly code.
Take dependency on factory method (as in Func<TestModel>) to create them as needed. With Unity you don't need to add any special registrations to get it working - it always registers both T and Func<T> (which is simply container => container.Resolve<T>()). With other containers you may need to either manually register it or even create factory interface.
public class GetTestRec
{
private Func<TestModel> _testModelFactory;
public GetTestRec(Func<TestModel> testModelFactory)
{
_testModelFactory = testModelFactory;
}
public TestModel Get(StructIn structIn)
{
TestModel newModel = _testModelFactory();
newModel.Name = structIn.Name;
newModel.Amount = structIn.Amount;
return newModel;
}
}

Related

Coming from EF to EF Core, how do I use the using statement correctly?

I must be doing something wrong in my context I have my context below which I want to wrap up in my manager class. And I want to be able to use the using statement so that my context is used only once.
public class xxxDbContext : DbContext
{
public xxxDbContext(DbContextOptions<xxxDbContext> options)
: base(options)
{ }
public DbSet<JobsList> JobListingss { get; set; }
public DbSet<Clients> ClientListings { get; set; }
public DbSet<Engineer> EngineerListing { get; set; }
public DbSet<Case> CasesListing { get; set; }
}
But when I want to use my context in my using statement such as
public class xxxContext
{
xxxDbContext _db = new xxxDbContext();
public List<Case> GetAllCases(int databaseId)
{
List<Case> q = new List<Case>();
using (var myContext = new xxxDbContext(what must I reference here ?)))
{
q = myContext.Cases
.Where(w => w.databaseID == databaseId)
.OrderBy(o => o.CustomerName).ToList();
}
return q;
}
}
Before I was just able to make a parameter less construct can I do same here for core or does that override what is meant to be done.
Also what is best practise should I have a separate class for all these functions or should I have a partial class based on my context?.
You will need to use the DbContextoptionsBuilder<T> generic class to get the instance of options back:
var optionsBuilder = new DbContextOptionsBuilder<xxxDbContext>();
and now you will have to use the created instance to be passed in the constructor:
using (var myContext = new xxxDbContext(optionsBuilder.Options)))
{
// code here
}
EDIT:
So what you need is first of all configure a service in services for getting the Options like:
public void ConfigureServices(IServiceCollection services)
{
// using sqlite as example via official docs example
services.AddDbContext<xxxDbContext>(options => options.UseSqlite("Data Source=blog.db"));
}
and then in the code where required to create the dbContext you could resolve it like:
var options = serviceProvider.GetService<DbContextOptions<xxxDbContext>>();
and now pass it to the Context class object creation time in constructor:
var options = serviceProvider.GetService<DbContextOptions<xxxDbContext>>();
using (var myContext = new xxxDbContext(options)))
{
// code here
}
You can refer to the following post for details at official docs:
Configuring a DbContext

Inject a property (recursively) without passing it as a parameter

I'm trying to achieve maybe something that might be impossible.
We have a big MVC 5 application. I created a small MVC project to simulate and explain what I want to apply into that big MVC project.
I have a controller that has unique Id. In this sample project the unique Id is regenerated for each request. In the MVC project, it is a bit more complex and different. However it's not relevant in the scope of this example.
public class FooController : Controller
{
public string UniqueId = Guid.NewGuid().ToString("N");
public ActionResult Index()
{
var worker = new WorkerA();
worker.DoWork();
return View();
}
}
The FooController creates WorkerA which creates WorkerB which creates WorkerC and so on. The workers are not the same. They don't have the same interface/implementation. To make the example simple I made them look similar.
Here's the Workers:
public class WorkerA
{
public string UniqueId = string.Empty;
public void DoWork()
{
var worker = new WorkerB();
worker.DoWork();
//...
//...
}
}
public class WorkerB
{
public string UniqueId = string.Empty;
public void DoWork()
{
var worker = new WorkerC();
worker.DoWork();
}
}
I want to have inject the property UniqueId into the worker without having to passing it as a parameter.
I want to avoid having to do this:
public WorkerA(string uniqueId)
{
UniqueId = uniqueId;
}
But I need to do the same for all the other workers.
EDIT
Is there a way to acheive that with ninject?
You can achieve what you want using Microsoft.Practices.Unity in the following manner:
public class WorkerA
{
[Dependency]
public string UniqueId { get; set; }
}
public class WorkerB
{
[Dependency]
public string UniqueId { get; set; }
}
And after that :
var container = new UnityContainer();
container.RegisterType<WorkerA>(new InjectionProperty(nameof(WorkerA.UniqueId),"WorkerAValue"));
container.RegisterType<WorkerA>(new InjectionProperty(nameof(WorkerB.UniqueId), "WorkerBValue"));
Later, you can request the instances from the container with the desired properties configured:
var workerA = container.Resolve<WorkerA>();
var workerB = container.Resolve<WorkerB>();
You can do something like:
worker.GetType().GetField("prop")?.SetValue(worker, "guid");
You could create a singleton class to manage the GUID and deliver it to the child classes that way. This way you can still do it in a constructor but not have to pass it as a parameter
public class GUIDManager
{
private static GUIDManager _instance;
private Guid _activeGuid;
public Guid ActiveGuid {
get { return _activeGuid; }
set { _activeGuid = value; }
}
private GUIDManager()
{
if (_activeGuid == null)
_activeGuid = new Guid();
}
public static GUIDManager GetInstance()
{
if(_instance == null)
{
_instance = new GUIDManager();
}
return _instance;
}
}
public class WorkerB
{
public string UniqueId = string.Empty;
public WorkerB()
{
var manager = GUIDManager.GetInstance();
UniqueId = manager.ActiveGuid.ToString();
}
public void DoWork()
{
var worker = new WorkerC();
worker.DoWork();
}
}
From your question i'm not entirely clear about all the workers in the same request getting the same ID or not. If they all should get the same ID then it's simple:
Wrap the ID in a class and use InRequestScope():
public class BrowserTabId
{
public string browserTabId;
public BrowserTabId(string tabId)
{
if(string.IsNullOrEmpty(tabId))
{
throw new NullArgumentException();
}
this.browserTabId = tabId;
}
public string Id { get { return this.browserTabId; } }
}
Bind<BrowserTabId>()
.ToMethod(ctx =>
new BrowserTabId(HttpContext.Items["BrowserTabId"] as string)))
.InRequestScope();
For testability reasons you can also slap on an interface IUniqueRequestId and create the binding for that.
This will result in all workers / objects created during the same request receiveing the same BrowserTabId. If you don't want to use c-tor injection you can use property injection instead. If you don't want to inject the value all the type, then use a When(..) condition to specify when to inject and when not to. Combine this with the null-object pattern to keep ninject from complaining that it can't inject a requested type.
Property Injection
Adapt a worker as follows:
public class WorkerA
{
[Inject]
public BrowserTabId BrowserTabId { get; set; }
....
}
Note, however, for this to work, like normal constructor injection, it is necessary that either the WorkerA is instanciated by ninject or that Ninject is informed about its existence by Ninject.Inject(workerAInstance)
Scoping
Since you mention that the lifetime of the ID in your actual application is somewhat more complicated, I guess you will have to use something different than InRequestScope - maybe roll your own scope (by using InScope(...)). Or Maybe, InCallScope() is as viable alternative. However, without knowing what exactly it is what you need, it's a bit difficult to advise you properly.

C# Cannot add or modify List in WCF

I am using example code from a tutorial on Creating a WCF Service and it only half works. Adding to the List works when it's hard-coded and retrieving the List works. However, using a routine to Add or modify the List does not work. Here is the code:
BookData.cs
using System.Runtime.Serialization;
namespace BookServicesV2
{
[DataContract]
public class BookData
{
[DataMember]
public int BookID { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Author { get; set; }
[DataMember]
public decimal Price { get; set; }
}
}
BookService.cs:
using System.Collections.Generic;
namespace BookServicesV2
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
public class BookService : IBookService
{
private List<BookData> _books;
private BookService()
{
_books = new List<BookData>();
var book = new BookData { BookID = 1, Author = "Shakespeare", Title = "To Be or Not To Be", Price = 1.49M };
_books.Add(book);
book = new BookData { BookID = 2, Author = "Mark Twain", Title = "Not Dead Yet", Price = 3.50M };
_books.Add(book);
}
#region IBookService Members
public void AddBook(BookData book)
{
if (book != null) _books.Add(book);
}
public void UpdatePrices(decimal increaseAmmount)
{
foreach (var book in _books)
{
book.Price += increaseAmmount;
}
}
public List<BookData> GetBooks()
{
return _books;
}
#endregion
}
}
When I launch the WCF Test Client, GetBooks retrieves the two hard-coded books. When I use AddBook or UpdatePrices and then GetBooks, nothing has changed. I'm basically learning c# and WCF on the fly, so I am completely stumped. Thanks!
Wcf by default create a new instance at each call. Every time you call the service on client, your list will allways have the two hardcoded books.
Check if you creating a new BookService For each Wcf request. You can change the InstanceContextMode to Single in your config or you can do it programatically so that just one instance is called for all requests. You can google out how to set this behaviour
Try changing the service behavior of your BookService.cs.
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single )]
public class BookService : IBookService{...}
This will change it to a singleton object. In other words, only 1 instance of your service is created.
You can also use InstanceContextMode = InstanceContextMode.PerSession as well. That means an object is created and maintained for each connection. If you close the connection and then re-connect you would have a new instance but you would be dealing with the same instance for each subsequent call you made to the service (assuming you don't close/reconnect).

Generic class constraint where <T> is a type constraining the generic class

Perhaps not the most accurate title, but it's a little difficult to describe; perhaps you guys can help me out here? I'm writing a game using the MVC format, and I want each base class (controller, model, and view) to have a reference to their accompanying features, forming a sort of triangle (ie. A model has a reference to a controller that defines it, and a view that references it, etc. ) Much of these classes look like this:
public class Model {
public Controller controller;
public View view;
public void Connect (Controller controller, View view) {
this.controller = controller;
this.view = view;
}
}
This is okay, but whenever I intend to pull up a ChildModel's controller, I'll need to cast to the appropriate ChildController to obtain the correct version. I could make a utility method/getter to fetch an appropriately cast item, but I'd rather not rewrite this piece of code for each and every child class. I thought I could solve this issue by making the base classes generic, but now I'm running into an issue where the newly generic classes need references to the class that's trying to define them, hence:
public class Model<V, C> where V : View<?, C> where C : Controller<?, V> {
public Controller<?, V> controller;
public View<?, C> view;
public void Connect (Controller<?, V> controller, View<?, C> view) {
this.controller = controller;
this.view = view;
}
}
As you can see, this quickly gets messy in the base class. I don't know what symbol to place for (in reference to the example above) the Model that's attempting to define the constraints. Placing 'Model' into the question marks doesn't seem to compile either, as I run into a hellish boxing conversion issue.
Is there a way to accomplish what I'm after, or am I just trying to be too clever here? If this could work, I'd love to be able to declare child classes with the type constrained to their 'triangle', thus I could avoid needless casting or helper methods:
public class ChildModel<ChildView, ChildController> {
public ChildModel () {
this.controller <- calls ChildController type, not base type!
}
}
Anyone have any ideas?
It looks like you are confusing ownership with interactions. Ownership implies that one owns the other, while interactions imply how they communicate with one another. MVC primarily defines interactions between the three participants, though you could say that a view and controller both own a model.
In your code as shown, a class owns a property, therefore a controller class owns a view and a view owns a controller.
var model = new Model();
var view = new View<Controller<Model, View<Controller, Model>, ...
This doesn't work with generics in the way you would like because the interactions become circular. It is the chicken and the egg problem: chickens come from eggs which are laid by chickens. We can solve most of the problem by giving the controller ownership of the view, and both the controller and view ownership of a model.
public class Model
{
}
public interface IView<M>
{
M Model { get; }
}
public class MyView : IView<Model>
{
public MyView(Model model)
{
Model = model;
}
public Model Model
{
get;
}
}
public interface IController<V, M>
{
M Model { get; }
V View { get; }
}
public class MyController : IController<MyView, Model>
{
public MyController(MyView view, Model model)
{
View = view;
Model = model;
}
public Model Model
{
get;
}
public MyView View
{
get;
}
}
We still used generics to do this, and you have easy access to most of the information so far without introducing circular references.
class Program
{
public static void Main()
{
var model = new Model();
var view = new MyView(model);
var controller = new MyController(view, model);
}
}
Now if you want to make sure the view has a reference to the controller, you can do this via a property.
view.Controller = controller;
You could disregard everything I just showed you - and go the property injection route. This means instead of taking in the dependencies by the constructor, which creates circular reference restrictions on how the objects can be created, you can simply do this.
var model = new Model();
var view = new View();
var controller = new Controller();
model.View = view;
model.Controller = controller;
view.Controller = controller;
view.Model = model;
controller.View = view;
controller.Model = model;
Whatever method you use, the trick is to avoid the circular dependency issue that you have in your current code. Most MVC frameworks provide rich data binding which breaks the direct coupling between the classes, but if you don't have that, you have to either write something or find something, or work within the confinements of the language rules.
There are a lot of ways to solve this. As I wrote this there was another answer posted so you should also look at that.
Here's my suggestion.
1. You should use the Controller as the main part of your MVC pattern. The controller should get the information from the Mode, process it and then call the view.
Here's my base class for the Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Inheritance.Classes
{
public class Controller<T, U> where T : Model, new() where U : View, new()
{
protected T _model;
protected U _view;
public Controller()
{
this._model = new T();
this._view = new U();
}
public Controller(T model, U view)
{
this._model = model;
this._view = view;
}
public string ParentFunction()
{
return "I'm the parent";
}
}
}
Note, I have also a Model and View base class. Since they are empty for the moment, I won't show you the code
Then, I can define my child classes. For example, I will make a PageController, PageModel and PageView. They will all inherite from their BaseClass.
Note : Once again, PageModel and PageView are empty. They are only used for the inheritance
PageController.cs
using Inheritance.Page;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Inheritance.Classes
{
public class PageController : Controller<PageModel, PageView>
{
public PageController():base()
{
}
public PageModel Model
{
get
{
return base._model;
}
}
}
}
So as you can see, you will specify the Model class and the View class only inside the PageController.
To use your classes, you can do as follow :
PageController controller = new PageController();
//We can access the parent function
Console.WriteLine(controller.ParentFunction());
//Function defined into the controller.
PageModel model = controller.Model;
I think this is what you want:
public class GameModel : Model
{
public int ID { get; set; }
}
public class GameView : View<GameModel, GameView>
{
public float FOV { get; set; }
}
public class GameController : GameView.BaseControler
{
// Set ID
public GameController()
{
Model.ID=100;
View.FOV=45f;
}
}
class Program
{
static void Main(string[] args)
{
var gm = new GameModel();
var view = new GameView();
var ctrl = new GameController();
view.Connect(gm, ctrl);
Debug.WriteLine(view.Model.ID);
}
}
public class Model
{
}
public class View<TModel,TView> where TModel : Model where TView : View<TModel, TView>
{
public TModel Model { get; private set; }
public BaseControler Controler { get; private set; }
public void Connect(TModel model, BaseControler controler)
{
this.Model=model;
this.Controler=controler;
this.Controler.Connect(model, this as TView);
}
public class BaseControler
{
public TView View { get; private set; }
public TModel Model { get; private set; }
public void Connect(TModel model, TView view)
{
this.Model=model;
this.View=view;
}
}
}

Retrieving records from another SQL Server database - Umbraco

I'm working on a website, where I need to retrieve pricelists, from another database on the same SQL Server as my Umbraco database.
It's a requirement that it has to be in a separate database.
I have made a new connection string Pricelist and used EF database-first.
PriceList repository:
namespace UmbracoCMS.Repository{
using System;
using System.Collections.Generic;
public partial class Prisliste
{
public string Kode { get; set; }
public string Speciale { get; set; }
public string Ydelsesgruppe { get; set; }
public string Gruppe { get; set; }
public string Ydelse { get; set; }
public string Ydelsestekst { get; set; }
public string Anaestesi { get; set; }
public string Indlæggelse { get; set; }
public Nullable<double> Listepris { get; set; }
public Nullable<int> WebSort { get; set; }
public string YdelsesTekstDK { get; set; }
public string Frapris { get; set; }
public Nullable<int> Sortering { get; set; }
}
}
PriceListController class:
using System;
using System.Linq;
using System.Web.Mvc;
using UmbracoCMS.Repository;
namespace UmbracoCMS.Controllers{
public class PriceListController : Umbraco.Web.Mvc.SurfaceController {
[HttpGet]
public PartialViewResult GetPriceList(string contentTitle){
var db = new PricelistContext();
var query = from b in db.Prislistes orderby b.Speciale select b;
Console.WriteLine("records in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Speciale);
}
return PartialView("~/views/partials/PriceList.cshtml");
}
}
}
What I want is to load the prices for a treatment, based on a property on the document type. I'm just not sure how do this in umbraco since I'm fairly new a umbraco.
So when a treatment page is requested, I need to take the property ContentTitle value. Use it to retrieve all records with the same Speciale and display them in a list/table.
With a query
.where(b.Speciale = contentTitle)
It would be great if someone could help a little, or lead me in the right direction.
Also is it possible to do it in the same http request? Or should I use partial view or macros to both get the properties of the document type, from the umbraco database, and the records from the pricelist database at the same time when a user go to the treatment page?
Or is there a better way to do this?
Update:
Thanks a lot, for the great answer Ryios.
I got a question more.
using System;
using System.Linq;
using System.Web.Mvc;
namespace UmbracoCMS.Controllers
{
public class PriceListSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
public ActionResult GetPriceList(string contentTitle)
{
PricelistContext.RunInContext(db =>
{
var result = db.Prislistes.OrderBy(p => p.Speciale);
});
return View(result);
}
}
}
I got it working, so it call the method and the data from the Pricelist Database is shown in:
var result = db.Prislistes.OrderBy(p => p.Speciale);
Now I just need to get the list of prices out to the view again, so I can show a list or table of the prices.
Do you have a suggestion on how I can this in Umbraco. Normally I would return a ViewModel in MVC like:
return View(new ListViewModel(result));
and use it in the view like:
#model Project.ViewModels.ListViewModel
So I can loop through it.
But I want to still have the properties from the the "Home"/"TreatmentPage" Document type.
Should I do it with a partialView or is there a better way?
Solved
I thought I wanted to share it, if anyone else is in a similar situaction.
Controller:
namespace UmbracoCMS.Controllers
{
public class PriceListSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
public PartialViewResult PriceList(string contentTitle)
{
List<Prisliste> result = null;
PricelistContext.RunInContext(db =>
{
result = db.Prislistes.Where(p => p.Speciale == contentTitle)
.OrderBy(p => p.Speciale).ToList();
});
var model = result.Select( pl => new PrislistVm()
{
Speciale = pl.Speciale,
Listepris= pl.Listepris
});
return PartialView(model);
}
}
}
ViewModel:
namespace UmbracoCMS.ViewModels
{
public class PrislistVm
{
public PrislistVm()
{
Results = new List<Prisliste>();
}
public List<Prisliste> Results { get; set; }
public string Speciale { get; set; }
public double listepris { get; set; }
}
}
View/PriceListSurface:
#model IEnumerable<UmbracoCMS.ViewModels.PrislistVm>
#{
ViewBag.Title = "PriceList";
}
<h2>PriceList</h2>
#foreach (var item in Model)
{
#item.Speciale
#item.Listepris
}
Your going to have a memory leak if you load your EF context like that. I recommend creating a method to wrap it for you with a llambda callback. Put it in your context class.
public static void RunInContext(Action<PricelistContext> contextCallBack)
{
PricelistContext dbContext = null;
try
{
dbContext = new PricelistContext();
contextCallBack(dbContext);
}
finally
{
dbContext.Dispose();
dbContext = null;
}
}
//Example Call
PricelistContext.RunInContext(db => {
var result = db.PrisListes.OrderBy(p => p.Speciale);
//loop through your items
});
To get the Value of the DocumentType, it depends on the calling context. Assuming you are using a Razor Template that is attached to the document type, that is associated with a Content Page.
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = "ContentPageLayout.cshtml";
}
#* Call GetPriceList on PriceListController with Parameter contentTitle *#
#Html.Action("GetPriceList", "PriceListSurface", new { contentTitle = Model.Content.GetPropertyValue<string>("ContentTitle") });
In the above example, I have created a document type with a property called ContentTitle that is associated with a view called ContentPage. Then I created content in the backoffice Content section called "Home" that uses the document type. Giving me a url like
http://localhost/home
Also, your SurfaceController will not work. Umbraco's logic for mapping the routes for surface controllers has some requirements for your surface controller's naming conventions. You have to end the name of the class with "SurfaceController" and then it get's called PriceListSurfaceController, then it maps the controller with a name of "PriceListSurface".
Here's the documentation for the SurfaceController features.
http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers
Using a surface controller is the right logic. It's not good practice to have your Data Layer code calls in the UmbracoTemplatePage. 1, because RazorTemplates are interpreted/compiled and SurfaceController's are JIT compiled int the dll, so SurfaceController code is WAY faster. 2 Because you can make asynchronous Controller calls in MVC Razor. If it was all in the view it would make it really difficult to convert everything to be asynchronous. It's best to keep server side logic in a controller.
Optionally, you can Hijack an Umbraco route and replace it with a custom controller that doesn't have to inherit from SurfaceController, which makes it possibly to surface content to the browser that is or isn't part of umbraco.
http://our.umbraco.org/documentation/Reference/Mvc/custom-controllers
You can also create a new section in the backoffice to manage your Price List "the ui framework for building one is written against AngularJS"
http://www.enkelmedia.se/blogg/2013/11/22/creating-custom-sections-in-umbraco-7-part-1.aspx

Categories