Repository Pattern For Accessing Text File - c#-4.0

I am fairly new to the Repository Pattern and I would like to do this correctly. I am also trying to make use of Inversion of Control (also new).
I would like to make sure I am using the repository pattern correctly.
I picked this up as an example of a base interface for my repositories.
public interface IRepository<T> where T : class
{
IEnumerable<T> Find(Expression<Func<T, bool>> where);
IEnumerable<T> GetAll();
void Create(T p);
void Update(T p);
}
IPaymentRepository is intended for extensions to IRepository (although I don't see why I would need this if I have the Find method above)
public interface IPaymentRepository : IRepository<Payment>
{
}
PaymentRepository simply reads a text file and builds a POCO.
public class PaymentRepository : IPaymentRepository
{
#region Members
private FileInfo paymentFile;
private StreamReader reader;
private List<Payment> payments;
#endregion Members
#region Constructors
#endregion Constructors
/// <summary>
/// Initializes a new instance of the <see cref="PaymentRepository"/> class.
/// </summary>
/// <param name="paymentFile">The payment file.</param>
public PaymentRepository(FileInfo paymentFile)
{
if (!paymentFile.Exists)
throw new FileNotFoundException("Could not find the payment file to process.");
this.paymentFile = paymentFile;
}
#region Properties
#endregion Properties
#region Methods
public IEnumerable<Payment> Find(Expression<Func<Payment, bool>> where)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets all payments from payment file.
/// </summary>
/// <returns>Collection of payment objects.</returns>
public IEnumerable<Payment> GetAll()
{
this.reader = new StreamReader(this.paymentFile.FullName);
this.payments = new List<Payment>();
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Payment payment = new Payment()
{
AccountNo = line.Substring(0, 11),
Amount = double.Parse(line.Substring(11, 10))
};
this.payments.Add(payment);
}
return this.payments;
}
public void Create(Payment p)
{
throw new NotImplementedException();
}
public void Update(Payment p)
{
throw new NotImplementedException();
}
#endregion Methods
I would like to know how to implement the Find method. I am assuming I would call GetAll and build an internal cache to the repository. For example, I would like to find all accounts that have payments greater than $50.

With your current IRepository signature you would implement it like this:
public IEnumerable<Payment> Find(Expression<Func<Payment, bool>> where)
{
this.reader = new StreamReader(this.paymentFile.FullName);
this.payments = new List<Payment>();
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Payment payment = new Payment()
{
AccountNo = line.Substring(0, 11),
Amount = double.Parse(line.Substring(11, 10))
};
if (where(payment)
{
this.payments.Add(payment);
}
}
return this.payments;
}
However, If your system memory allows it, you could keep a cached list (from GetAll()) and use Find() on the list. This should be an order of magnitude faster depending on the size of your list.

Related

How do I communicate between two sibling Blazor components?

I have a Blazor page with two components. One component has a button which generates a random number when clicked. The other component has a text area which should display the generated random number.
<h1>Parent Page</h1>
<ProvideNumberComponent />
<DisplayNumberComponent />
#code {
}
<h3>Provides Number</h3>
<button class="btn btn-primary" #onclick="CalculateNumber">Provide Number</button>
#code {
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
}
}
<h3>Displays number</h3>
<textarea cols="9" rows="1" readonly style="font-family:monospace;" />
#code {
}
What is the cleanest way to get the number from the calculate sibling component to appear in the display sibling component?
A problem with my code is that the Random object is instantiated on every button click, instead of once on initialization. Is this best addressed by placing the Random object in a singleton service class, and injecting that into the calculate component?
The best solution, to my mind, is to create a service which implements the state pattern and the notifier pattern. The following code describes how communication between two sibling can be done through an intermediary
NotifierService.cs
public class NotifierService
{
public NotifierService()
{
}
int rnd;
public int RandomNumber
{
get => rnd;
set
{
if (rnd != value)
{
rnd= value;
if (Notify != null)
{
Notify?.Invoke();
}
}
}
}
public event Func<Task> Notify;
}
Add this: services.AddScoped<NotifierService>();
ProvideNumberComponent.razor
#inject NotifierService Notifier
#implements IDisposable
<h3>Provides Number</h3>
<button class="btn btn-primary" #onclick="CalculateNumber">Provide
Number</button>
#code
{
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
Notifier.RandomNumber = nextNumber;
}
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
protected override void OnInitialized()
{
Notifier.Notify += OnNotify;
}
public void Dispose()
{
Notifier.Notify -= OnNotify;
}
}
DisplayNumberComponent.cs
#inject NotifierService Notifier
#implements IDisposable
<hr />
<h3>Displays number</h3>
<textarea cols="9" rows="1" readonly style="font-family:monospace;">
#Notifier.RandomNumber
</textarea>
#code {
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
protected override void OnInitialized()
{
Notifier.Notify += OnNotify;
}
public void Dispose()
{
Notifier.Notify -= OnNotify;
}
}
Of course you can inject and use the service in multiple components, as well as adding more features that the service can provide.
Implementing communication by means of event handlers may be problematic, unless it is between a parent and its child...
Hope this works...
Indeed there are many ways to accomplish your goal, I just want to show you the way I like more:
Parent Component:
<EditForm Model="Message">
<PageOne #bind-Send="Message.Text"/>
<PageTwo #bind-Receive="Message.Text"/>
</EditForm>
#code{
public Content Message { get; set; }=new Index.Content();
public class Content
{
public string Text { get; set; } = "Hello world";
}
}
PageOne component - the one who send the value:
<button #onclick="#GetGuid">Change value</button>
#code{
[Parameter] public string Send { get; set; }
[Parameter] public EventCallback<string> SendChanged { get; set; }
async void GetGuid()
{
await SendChanged.InvokeAsync(Guid.NewGuid().ToString());
}
}
PageTwo the component which will receive the data
<h1>#Receive</h1>
#code{
[Parameter] public string Receive { get; set; }
[Parameter] public EventCallback<string> ReceiveChanged { get; set; }
}
Explanations:
Usually when we need to communicate, we need a third party service, and in this case I used the EditForm component, which can store a Model and the properties of this model can be shared by all child components.
I also made a custom component, with less functionality, and I named PhoneBox (to be used instead EditForm), just to be obvious the role :)
PhoneBox - third party communication service :)
<CascadingValue Value="EditContext">
#ChildContent(EditContext)
</CascadingValue>
#code {
[Parameter] public object Model { get; set; }
[Parameter]public EditContext EditContext { get; set; }
[Parameter] public RenderFragment<EditContext> ChildContent { get; set; }
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
}
}
I like more this approach because look's more "blazor way" :)
Look how nice is "blazor way"
<PhoneBox Model="Message">
<PageOne #bind-Send="Message.Text"/>
<PageTwo #bind-Receive="Message.Text"/>
</PhoneBox>
You can see a working example Working Example
I think interfaces are the best way to do this.
This is from my Nuget package, DataJugger.Blazor.Components
Interface IBlazorComponent:
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponent
/// <summary>
/// This interface allows communication between a blazor componetn and a parent component or page.
/// </summary>
public interface IBlazorComponent
{
#region Methods
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#endregion
#region Properties
#region Name
/// <summary>
/// This property gets or sets the Name.
/// </summary>
public string Name { get; set; }
#endregion
#region Parent
/// <summary>
/// This property gets or sets the Parent componet or page for this object.
/// </summary>
public IBlazorComponentParent Parent { get; set; }
#endregion
#endregion
}
#endregion
}
Interface IBlazorComponentParent
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponentParent
/// <summary>
/// This interface is used to host IBlazorComponent objects
/// </summary>
public interface IBlazorComponentParent
{
#region Methods
#region FindChildByName(string name)
/// <summary>
/// This method is used to find a child component that has registered with the parent.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
IBlazorComponent FindChildByName(string name);
#endregion
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#region Refresh()
/// <summary>
/// This method will call StateHasChanged to refresh the UI
/// </summary>
void Refresh();
#endregion
#region Register(IBlazorComponent component)
/// <summary>
/// This method is called by the Sprite to a subscriber so it can register with the subscriber, and
/// receiver events after that.
/// </summary>
void Register(IBlazorComponent component);
#endregion
#endregion
#region Properties
#region Children
/// <summary>
/// This property gets or sets the value for Children.
/// </summary>
public List<IBlazorComponent> Children { get; set; }
#endregion
#endregion
}
#endregion
}
For usage, here is the most relevant parts:
In your component, which is an IBlazorCompoent (child), there is a Parent property.
In your component, you set the parent like this:
<Login Parent=this></Login>
Then in your component, you alter the parent property like this:
[Parameter]
public IBlazorComponentParent Parent
{
get { return parent; }
set
{
// set the value
parent = value;
// if the Parent exists
(Parent != null)
{
// Register with the parent
Parent.Register(this);
}
}
}
Next, in your parent component that implements IBlazorComponentParent, add a property for your component and change the Register method to this:
// Login component reference
public Login LoginComponent { get; set; }
public void Register(IBlazorComponent component)
{
if (component is Login)
{
// Store the LoginComponent
LoginComponent = component as Login;
}
else if (component is Join)
{
// Store the compoent
SignUpComponent = component as Join;
}
}
Now at this point, my Login component knows about the parent and the parent knows about the Login, so I can sent messages like this:
From the child, send a simple message:
if (Parent != null)
{
Message message = new Message();
message.Text = "Some message";
Parent.SendMessage(message);
}
Or send a complex message
// create a message
DataJuggler.Blazor.Components.Message message = new DataJuggler.Blazor.Components.Message();
// Create the parameters to pass to the component
NamedParameter parameter = new NamedParameter();
// Set the name
parameter.Name = "PixelInformation Update";
parameter.Value = pixel;
// Create a new collection of 'NamedParameter' objects.
message.Parameters = new List<NamedParameter>();
// Add this parameter
message.Parameters.Add(parameter);
// Send this to the component
ColorPickerComponent.ReceiveData(message);
Then in the parent to receive the message:
public void ReceiveData(Message message)
{
// If the message object exists and has parameters
if ((message != null) && (message.HasParameters))
{
// if this a PixelInformation update from the Index page
if (message.Parameters[0].Name == "PixelInformation Update")
{
// this is only relevant to my app, just showing an example of
// \what I do with the data after it is received.
// Set the SelectedPixel
SelectedPixel = (PixelInformation) message.Parameters[0].Value;
// Set the properties from the Pixel to display
SetupColorPicker();
}
}
}
The above code is used in my newest site, PixelDatabase.Net https://pixeldatabase.net
The Nuget package code is all open source if anyone wants it:
DataJuggler.Blazor.Components
https://github.com/DataJuggler/DataJuggler.Blazor.Components
I come from a Windows Forms background, so I love being able to communicate between components like this, which data binding doesn't always work.
this.Login.DoSomething(data);
You can also cast the parent as a specific type like this:
public IndexPage ParentIndexPage
{
get
{
// cast the Parent object as an Index page
return this.Parent as IndexPage;
}
}
So your child can call methods or set properties on the parent, if the parent exists of course, so always add a:
public bool HasParentIndexPage
{
get
{
// return true if the ParentIndexPage exists
return (ParentIndexPage != null);
}
}
So then for easy usage from the child:
// if the parent index page exists
if (HasParentIndexPage)
{
// Safely call your parent page
ParentIndexPage.SomeMethod();
}
On way to do it would absolutely be to use the session pattern and inject the same instance in both components and then notify them onchange. A faster way would probably be to use the two way binding and eventcallbacks.
In ProvideNumberComponent.razor
<button class="btn btn-primary" #onclick="CalculateNumber">Provide Number</button>
#code {
[Parameter]
public EventCallback<int> OnRandomNumberSet{get; set;}
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
OnRandomNumberSet.InvokeAsync(nextNumber);
}
}
In ParentComponent.razor
<h1>Parent Page</h1>
<ProvideNumberComponent OnRandomNumberSet="((r) => SetRandomNumber(r))"/>
<DisplayNumberComponent TextAreaValue="_randomNumber" />
#code {
private int _randomNumber;
private void SetRandomNumber(int randomNumber)
{
_randomNumber = randomNumber;
}
}
In DisplayNumberComponent.razor
<h3>Displays number</h3>
<textarea cols="9" rows="1" bind:value="TextAreaValue" readonly style="font-family:monospace;" />
#code
{
[Parameter]
public int TextAreaValue{get; set;}
}
MDSN has an example using DI injected Notifier service
invoke component methods externally to update state, which should work for any component-relation (not only siblings).
At a steeper learning curve, but more maintenance-friendly + scaleable in the long run is the Flux/Redux library Fluxor
For anyone trying to get an overview of more "design-pattern"'ish solutions, MVVM is also a posibility, example here: MVVM example implementation 4 Blazor

Building processing screen for customer locations

I need to build a processing screen for customer locations that determines and then updates the residential flag on locations.
This code correctly processes each selected record and appears to update the appropriate fields. But the problem I am encountering is that my changes to Location are not being saved back to the database.
The Customer Locations graph requires the business account to be specified before you can enter a Location ID, and I suspect that because of that I cannot simply update the Locations view on the graph. But I cannot find any documentation or code examples indicating what approach I should use here.
Here is the code on my processing screen graph:
public class ProcessCustomerLocations : PXGraph<ProcessCustomerLocations>
{
public PXCancel<Location> Cancel;
public PXProcessing<Location, Where<Location.isActive, Equal<True>>> Locations;
public static void Process(List<Location> locations)
{
var graph = PXGraph.CreateInstance<CustomerLocationMaint>();
CustomerLocationMaint_Extension graphExt = graph.GetExtension<CustomerLocationMaint_Extension>();
foreach (var location in locations)
{
graphExt.UpdateLocation(location, true);
}
}
public ProcessCustomerLocations()
{
Locations.SetProcessDelegate(Process);
}
}
And here is my code on the CustomerLocationMaint_Extension graph:
public class CustomerLocationMaint_Extension : PXGraphExtension<CustomerLocationMaint>
{
public void UpdateLocation(Location location, bool isMassProcess = false)
{
bool isRes = false;
Base.Location.Current = Base.Location.Search<Location.locationID>(location.LocationID, location.BAccountID);
LocationExt locationExt = location.GetExtension<LocationExt>();
// INSERT CODE TO DETERMINE VALUE OF isRes
locationExt.UsrResidentialValidated = true;
location.CResedential = isRes;
Base.Location.Update(location);
Base.Actions.PressSave();
}
}
One of the fields I am updating on Location is a custom field called UsrResidentialValidated. Here is the code for that field.
namespace PX.Objects.CR
{
public class LocationExt : PXCacheExtension<PX.Objects.CR.Location>
{
#region UsrResidentialValidated
[PXDBBool]
[PXUIField(DisplayName="Residential Validated")]
public virtual bool? UsrResidentialValidated { get; set; }
public abstract class usrResidentialValidated : IBqlField { }
#endregion
}
}
Update
Thanks to some help from #Samvel I've modified the UpdateLocation code as follows. The following code does save the changes to the database (both on the custom field and the non-custom field), which is great. However, in order to do that, I had to create a new Location object "myLocation" and am no longer using the "location" object that the PXProcessing graph passed to UpdateLocation. This means that after processing, when the processing screen displays the processed records with the modified data (after processing finishes and before you refresh the screen), it does not show the updated values. Is there any way to both have the processing screen show the updated values and save the changes to the database?
public void UpdateLocation(PX.Objects.CR.Location location, bool isMassProcess = false)
{
bool isRes = true;
Location myLocation = PXSelect<Location,
Where<Location.bAccountID, Equal<Required<Location.bAccountID>>, And<Location.locationID, Equal<Required<Location.locationID>>>>>
.Select(this.Base, location.BAccountID, location.LocationID);
this.Base.Location.Current = myLocation;
LocationExt locationExt = myLocation.GetExtension<LocationExt>();
locationExt.UsrResidentialValidated = true;
myLocation.CResedential = isRes;
Base.Location.Current = Base.Location.Update(myLocation);
this.Base.Save.Press();
}
UPDATED
I have updated the code to correspond to your case. After processing all the records the records in the grid are being updated and showing modified records.
You can download the customization package for this code by this link
To create a processing page for updating Location you should do the following steps:
Add "Selected" field to the Location DAC
public sealed class LocationExt: PXCacheExtension<Location>
{
#region Selected
public abstract class selected : IBqlField
{ }
[PXBool()]
[PXDefault(true,PersistingCheck = PXPersistingCheck.Nothing)]
[PXUIField(DisplayName = "Selected")]
public bool? Selected { get; set; }
#endregion
#region UsrResidentialValidated
[PXDBBool]
[PXUIField(DisplayName = "Residential Validated")]
public bool? UsrResidentialValidated { get; set; }
public abstract class usrResidentialValidated : IBqlField { }
#endregion
}
This step is required because otherwise your delegate for SetProcessDelegate will never be called.
Acumatica is checking if there is at least one selected record before calling Process Delegate.
Create the Processing Graph like below:
using PX.Data;
using PX.Objects.CR;
using System.Collections.Generic;
namespace CustomerLocationUpdate
{
public class ProcessCustomerLocations : PXGraph<ProcessCustomerLocations>
{
public PXCancel<Location> Cancel;
public PXProcessingJoin<Location,InnerJoin<BAccountR,On<Location.bAccountID,Equal<BAccountR.bAccountID>>>,
Where<Location.isActive, Equal<True>,And<Location.locType, Equal<PX.Objects.CR.LocTypeList.customerLoc>>>> Locations;
public static void Process(List<Location> locations)
{
var graph = PXGraph.CreateInstance<PX.Objects.AR.CustomerLocationMaint>();
CustomerLocationMaint_Extension graphExt = graph.GetExtension<CustomerLocationMaint_Extension>();
foreach (var location in locations)
{
graphExt.UpdateLocation(location, true);
graph.Clear();
}
}
public ProcessCustomerLocations()
{
Locations.SetProcessDelegate(Process);
}
}
}
As you can see I have implicitly specified PX.Objects.AR and PX.Objects.CR for some reason the program has worked only this way on my instance.
Create the UpdateLocation method in the GraphExtension:
using PX.Data;
namespace CustomerLocationUpdate
{
public class CustomerLocationMaint_Extension : PXGraphExtension<PX.Objects.AR.CustomerLocationMaint>
{
public void UpdateLocation(PX.Objects.CR.Location location, bool isMassProcess = false)
{
bool isRes = false;
this.Base.Location.Current = PXSelect<PX.Objects.CR.Location,Where<PX.Objects.CR.Location.bAccountID,Equal<Required<PX.Objects.CR.Location.bAccountID>>,And<PX.Objects.CR.Location.locationID,Equal<Required<PX.Objects.CR.Location.locationID>>>>>.Select(this.Base,location.BAccountID,location.LocationID);
this.Base.Location.Current.CResedential = isRes;
LocationExt locationExt = PXCache<PX.Objects.CR.Location>.GetExtension<LocationExt>(this.Base.Location.Current);
locationExt.UsrResidentialValidated = false;
this.Base.Location.Current = this.Base.Location.Update(this.Base.Location.Current);
this.Base.Save.Press();
}
}
}
As you can see I am setting the Location.Current using PXSelect and not Location.Current.Search.
For some reason Location.Current.Search is always returning null.
May be it is caused by the PXProjectionAttribute applied to it, I am not sure what is the exact reason.

Tree View in ASP.NET MVC5

I need to create a tree view in asp.net mvc5 framework for the recursive outputs.
This is my model class
public class ProcSearchModel
{
/// <summary>
///
/// </summary>
public string TableName { get; set; }
/// <summary>
///
/// </summary>
public string DirectoryPath { get; set; }
/// <summary>
///
/// </summary>
public List<string> ProceduresName { get; set; }
// public List<ProcSearchModel> =
}
That stores the list of result in ProceduresName list.
Now for each Procedure name in the list there is another list of names in it. Which I need to populate as tree view..
Presently this is my controller function:
public ActionResult SearchProcedure(ProcSearchModel procSearchModel)
{
List<string> lstString = new List<string>();
//if (procSearchModel != null)
//{
try
{
var txtFiles = Directory.EnumerateFiles(procSearchModel.DirectoryPath, "*.sql", SearchOption.AllDirectories);
// pattern to capture the Stored procedue name
// string cpattern = #"(CREATE PROCEDURE|ALTER PROCEDURE)\s*(?<proc_name>(\w|_|\[|\]|\.)*)(.|\n)*" + procSearchModel.TableName;
string cPattern = #"(CREATE PROCEDURE|ALTER PROCEDURE)\s*(?<proc_name>(\w|_|\[|\]|\.)*)";
string tPattern = procSearchModel.TableName;
foreach (string currentFile in txtFiles)
{
string content = System.IO.File.ReadAllText(currentFile);
if(Regex.IsMatch(content,tPattern,RegexOptions.IgnoreCase) && Regex.IsMatch(content,cPattern,RegexOptions.IgnoreCase))
{
Match match = Regex.Match(content, cPattern, RegexOptions.IgnoreCase);
lstString.Add(match.Groups["proc_name"].Value);
}
}
procSearchModel.ProceduresName = lstString;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//}
return View(procSearchModel);
}
Now plz help me how to populate the tree view by usnig nested list with jstree plugin
Create a recursive node structure of the nodes (or objects) as you need in the hierarchy and link them as in a tree. Then pass that object in a tree
class dummyObject{
int num;
String data;
List<dummyObject> d = new List<dummyObject>();
}
Use this type of class object to create hierarchy structure and then pass them into jstree (http://www.jstree.com/) plugin call..... Rest will be done the plugin.

error CS0738 Interface implementation

I have the following interface:
public delegate void NotifyOnModulesAvailabilityHandler(Lazy[] modules);
public interface IModulesLoader
{
event NotifyOnModulesAvailabilityHandler NotifyOnModulesAvailability;
Lazy<UserControl, IModuleMetadata>[] Modules { get; set; }
void OnImportsSatisfied();
}
I'm tring to implement this interface like this:
public class ModulesLoader : IModulesLoader, IPartImportsSatisfiedNotification
{
#region Events
public event NotifyOnModulesAvailabilityHandler NotifyOnModulesAvailability;
#endregion
#region Public Contructor
public ModulesLoader()
{
DeploymentCatalogService.Instance.Initialize();
CompositionInitializer.SatisfyImports(this);
this.LoadModules();
}
#endregion
#region Properties
[ImportMany(AllowRecomposition = true)]
public Lazy<UserControl, IModuleMetadata>[] Modules
{
get;
set;
}
#endregion
#region IPartImportsSatisfiedNotification Members
public void OnImportsSatisfied()
{
var handler = this.NotifyOnModulesAvailability;
if (handler != null)
{
handler(this.Modules);
}
}
#endregion
#region Private Methods
private void LoadModules()
{
var wc = new WebClient();
wc.OpenReadCompleted += (s, e) =>
{
var streamInfo = e.Result;
var xElement = XElement.Load(streamInfo);
var modulesList = from m in xElement.Elements("ModuleInfo")
select m;
if (modulesList.Any())
{
foreach (var module in modulesList)
{
var moduleName = module.Attribute("XapFilename").Value;
DeploymentCatalogService.Instance.AddXap(moduleName);
}
}
};
wc.OpenReadAsync(new Uri("ModulesCatalog.xml", UriKind.Relative));
}
#endregion
}
I get the following error:
Error 1 'TunisiaMeeting.Extensibility.Shell.Helpers.Deployment.ModulesLoader' does not implement interface member 'TunisiaMeeting.MefBase.Interfaces.IModulesLoader.Modules'. 'TunisiaMeeting.Extensibility.Shell.Helpers.Deployment.ModulesLoader.Modules' cannot implement 'TunisiaMeeting.MefBase.Interfaces.IModulesLoader.Modules' because it does not have the matching return type of 'System.Lazy``2<System.Windows.Controls.UserControl,TunisiaMeeting.MefBase.Interfaces.IModuleMetadata>[]'. C:\Imed\TunisiaMeeting\TunisiaMeeting.Extensibility.Shell\Helpers\Deployment\ModulesLoader.cs 18 18 TunisiaMeeting.Extensibility.Shell
I'm pretty sure I have the same return Type Lazy<UserControl, IModuleMetadata>[] in both my class and my interface for my property.
Any Help please ?
Thank you all
You haven't shown where UserControl and IModuleMetadata come from... my guess is that your interface is referring to one pair of types whereas your implementation is referring to a different pair:
Make sure they're referring to the same types in the same namespaces
Make sure you only have one copy of each type (e.g. that you haven't got one copy in a class library, and redeclared it somewhere else)

The entity type IdentityRole is not part of the model for the current context

I am having trouble implementing ASPNetIdentity on my MVC project
I am getting this error in the var line (The entity type IdentityRole is not part of the model for the current context.):
using System;
using System.Linq;
using System.Web.Mvc;
using EZ.Models;
using Microsoft.AspNet.Identity.EntityFramework;
namespace EZ.Controllers
{
public class RoleController : Controller
{
ApplicationDbContext context;
public RoleController()
{
context = new ApplicationDbContext();
}
/// <summary>
/// Get All Roles
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
var roles = context.Roles.ToList();
return View(roles);
}
/// <summary>
/// Create a New role
/// </summary>
/// <returns></returns>
// GET: /Roles/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Roles/Create
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
{
Name = collection["RoleName"]
});
context.SaveChanges();
ViewBag.ResultMessage = "Role created successfully !";
return RedirectToAction("Index");
}
catch
{
return View();
}
}
/// <summary>
/// Set Role for Users
/// </summary>
/// <returns></returns>
public ActionResult SetRoleToUser()
{
var list = context.Roles.OrderBy(role => role.Name).ToList().Select(role => new SelectListItem { Value = role.Name.ToString(), Text = role.Name }).ToList();
ViewBag.Roles = list;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UserAddToRole(string uname, string rolename)
{
ApplicationUser user = context.Users.Where(usr => usr.UserName.Equals(uname, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
// Display All Roles in DropDown
var list = context.Roles.OrderBy(role => role.Name).ToList().Select(role => new SelectListItem { Value = role.Name.ToString(), Text = role.Name }).ToList();
ViewBag.Roles = list;
if (user != null)
{
var account = new AccountController();
account.UserManager.AddToRoleAsync(user.Id, rolename);
ViewBag.ResultMessage = "Role created successfully !";
return View("SetRoleToUser");
}
else
{
ViewBag.ErrorMessage = "Sorry user is not available";
return View("SetRoleToUser");
}
}
}
}
I have scripted the tables in my DB.
This is the exact same code as in the role-security-mvc5-master project from CodeProject.com. The only difference is that I moved the tables in my DB ana dI changed the connection string. What is the piece I am missing?
in my IdentityModel.cs I have:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
If you need more code, please let me know and I will post.
When the project was created, identity, a database at locadb. when I moved the tables in my DB I overwrote the entire Default connection string with the one I created for E. The big probelm here was that the default connection needs providerName="System.Data.SqlClient" /> and NOT providerName="System.Data.EntityClient". Be careful there. Credit needs to go to this excellent article from Daniel Eagle: http://danieleagle.com/blog/2014/05/setting-up-asp-net-identity-framework-2-0-with-database-first-vs2013-update-2-spa-template/. Tons of detail on how to use Identity with DB first.

Resources