So I have been stuck with this issue for quite some time. We are implementing a DDD architecture and I don't want our models or entities to be anemic.
We are also using EF6 and Autofac. I don't want to implement a repository pattern as EF already acts as this pattern.
So say for instance we have a context called TestContext
public class TestContext : DbContext
{
public TestContext() : base("TestContext")
{
}
public DbSet<AEntity> AEntities { get; set; }
}
The one DBset it has is AEntity
public class AEntity
{
public ITest testService;
public Guid Id { get; set; }
public string Name { get; private set; }
public AEntity()
{
}
public AEntity(string name)
{
this.Name = name;
}
public virtual void Test()
{
// Logic.
// Global testLogic for names
testService.Test(this.Name);
}
}
So I have autoface configured to autowire property injection
builder.RegisterType<AEntity>().PropertiesAutowired();
and this works a charm if autofac is responsible for instantiating the instance like the following method shows:
public ValuesController(AEntity aEntity)
{
aEntity.Test();
}
Great it works and everything but here comes the catch when I do something like this
public ValuesController(TestContext context)
{
var a = context.AEntities.FirstOrDefault();
a.Do();
}
The ITest is not getting autowired, and I know its due to that autofac is not the instantiater or resolver, but this is something that I want to accomplish.
Any pointers and let me know if my question does not make sense.
I'm using Entity Framework and .Net Core 2.0 for the first time (I'm also pretty new to C#, but I've been using the traditional .Net Framework & VB since version 1... so I'm no newbie to .Net development), and I've already run into a problem creating my database.
Take this simple scenario: I want to store some information about some electric pumps. Two of the properties are a min/max type range, so I've implemented these as a simple class, thus:
public class Pump
{
[Key]
public int pumpId { get; set; }
public string pumpName { get; set; }
public int pumpControlChannel { get; set; }
public MinMax normalCurrent { get; set; }
public MinMax normalFlowRate { get; set; }
}
[ComplexType]
public class MinMax
{
public int min { get; set; }
public int max { get; set; }
}
As you can see, I've tried the [ComplexType] decorator, to no avail.
Anyway, now create a dead simple DBContext class to manage my Pumps class. I'm using Sqlite:
public class EFDB : DbContext
{
public DbSet<Pump> pumps { get; private set; }
private static DbContextOptions GetOptions(string connectionString)
{
var modelBuilder = new DbContextOptionsBuilder();
return modelBuilder.UseSqlite(connectionString).Options;
}
public EFDB(string connectionString) : base(GetOptions(connectionString)) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
try
{
// modelBuilder.ComplexType<MinMax>(); // ComplexType not recognised
base.OnModelCreating(modelBuilder);
}
catch (Exception ex)
{
System.Diagnostics.Debugger.Break();
}
}
}
and lastly a simple static class to call it (I embeded it in a bigger program... to duplicate this problem you could just stick the code lines into program.cs):
public static class TryMe
{
public static void MakeMeFail()
{
using (var db = new EFDB("FileName=C:\\temp\\test_effail.db"))
{
try
{
db.Database.EnsureCreated();
}
catch (Exception ex)
{
System.Diagnostics.Debugger.Break(); // If we hit this line, it fell over
}
}
System.Diagnostics.Debugger.Break(); // If we hit this line, it worked.
}
}
Just call TryMe.MakeMeFail(), the code fails at db.Database.EnsureCreated().
From everything I've read, [ComplexType] should do what I want... but it Just Doesn't. Nor can I find modelBuilder.ComplexType<T> anywhere.
It may just be a library reference I'm missing...? The above code uses the following:
using System;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
However, NONE of the documentation/examples I can find anywhere show which libraries need referencing!
Thanks in advance.
[PS: Apologies to those who already saw this question, I'm using EF Core 2.0, NOT EF6]
Typical... it's always the way, isn't it? 5 minutes after posting, you discover the answer to your own question....
The answer, in this case, can be found here:
https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities
EF Core calls this sort of entity an "owned" entity, rather than a "complex type".
Simply adding these lines to `OnModelCreating' fixed the issue:
modelBuilder.Entity<Pump>().OwnsOne(p => p.normalCurrent);
modelBuilder.Entity<Pump>().OwnsOne(p => p.normalFlowRate);
The database now creates (correctly, I think, I haven't verified that yet).
I use Dapper and TableAttribute:
using Dapper.Contrib.Extensions;
namespace MyCompany.Entities
{
[Table(Config.TABLE_ARCHIVO_CLIENTE)]
public partial class ArchivoCliente
{
Working
public const string TABLE_ARCHIVO_CLIENTE = "Archivo_Cliente";
Not working if not const string. I try use a static property for use appSettings:
public static string TABLE_ARCHIVO_CLIENTE
{
get
{
return ConfigurationManager.AppSettings.Get(KeyTable);
}
}
Any suggestions for using AppSettings ?
Attribute parameters require constants.
Checking the Dapper.Contrib code, it appears very unusually to access the attribute by name. If it was by type, you could do something like:
class ConfigTableAttribute : TableAttribute {
public ConfigTableAttribute(string configSetting)
: base(LookupTableNameFromConfig(configSetting));
private static string LookupTableNameFromConfig(string configSetting)
{
// TODO: your code here
}
}
and annotate your code with:
[ConfigTable(nameof(Config.TABLE_ARCHIVO_CLIENTE))]
class Foo {}
It would then be your job to implement the TODO which would fetch the actual value via reflection or an indexer, etc. In the code shown, the input configSetting would be TABLE_ARCHIVO_CLIENTE.
However, since it accesses it by name and dynamic, all you actually need is something called TableAttribute that has a Name. You could do the same thing as above, but in a different namespace:
namespace MyEvilness {
class TableAttribute : Attribute {
public TableAttribute(string configSetting) {
Name = LookupTableNameFromConfig(configSetting);
}
// etc as before
}
}
and use:
[MyEvilness.Table(nameof(Config.TABLE_ARCHIVO_CLIENTE))]
class Foo {}
Word of caution; I consider the current implementation to be a bug! I understand why it is done that way (i.e. so it works with EF), but I'm tempted to make it work for either approach.
I've written a small package to overcome this issue. It assigns the value as tablename if the key matches to FullName, in the configuration file. With some effort spend to avoid sql injection.
One can add it like dependency injection
// Startup.cs or Program.cs
// ...
services.ReadTablenamesFromConfig(configuration.GetSection("MySectionName"));
// ...
with configuration:
// appsettings.json
...
"MySectionName": {
"TableNames": {
"Demo.Sale": "sale_2020"
}
},
...
For the model:
// Sale.cs
namespace Demo
{
//[Table("sale_2020")]
public class Sale
{
public string Product { get; set; }
public int Quantity { get; set; }
}
}
See a better example here.
As for the time being, the implementation is as follows:
// TablenameExtensions.cs
using Dapper.Contrib.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Dapper.Contrib.Extensions.Tablename
{
public static class TablenameExtensions
{
private static TablenameConfig _config;
public static IServiceCollection ReadTablenamesFromConfig(this IServiceCollection services, IConfigurationSection configSection)
{
services.Configure<TablenameConfig>(configSection);
_config = configSection.Get<TablenameConfig>();
SqlMapperExtensions.TableNameMapper = TableName;
return services;
}
private static string TableName(Type type) => _config.TableNames[type.FullName].Replace("`", "");
public static string TableName<T>() => TableName(typeof(T));
}
}
where:
// TablenameConfig.cs
using System.Collections.Generic;
namespace Dapper.Contrib.Extensions.Tablename
{
internal class TablenameConfig
{
public IDictionary<string, string> TableNames { get; set; }
}
}
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;
}
}
}
I'm new to MVC and struggling to implement a ViewModel to query multiple tables. Initially my setup worked perfectly but now having reloaded the project I am getting a compilation error as copied below:
Cannot implicitly convert type 'System.Collections.Generic.List<CATEGORY>' to 'System.Collections.Generic.List<TestProject.Models.CATEGORY>'
ViewModel code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProject.Models
{
public class COMPCATEGORY
{
public List<COMP> Comp { get; set; }
public List<CATEGORY> Category { get; set; }
}
}
Controller Code:
namespace TestProject.Controllers
{
public class COMPsController : Controller
{
private mattbeaneyEntities1 db = new mattbeaneyEntities1();
// GET: COMPs
public ActionResult Index()
{
COMPCATEGORY viewModel = new COMPCATEGORY();
viewModel.Category = db.CATEGORies.ToList();
viewModel.Comp = db.COMPs.ToList();
return View(viewModel);
}
DB Context code:
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class mattbeaneyEntities1 : DbContext
{
public mattbeaneyEntities1()
: base("name=mattbeaneyEntities1")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<CATEGORY> CATEGORies { get; set; }
public virtual DbSet<COMP> COMPs { get; set; }
}
As the error suggests it is having trouble with two types by the same name, when we were only expecting one. The namespace is our clue here:
Cannot implicitly convert type 'System.Collections.Generic.List<CATEGORY>' to 'System.Collections.Generic.List<TestProject.Models.CATEGORY>'
Usually there are a couple of things I like to check in this case:
Firstly: are there two classes that share the same name and belong to different namespaces? It's quite easy to do as your project grows!
Secondary: has the main project namespace changed? Sometimes due to a bit of refactoring we change the project name and then end up with two .dll files in the bin folder, which hold duplicate of all our classes - delete the old one!