How do use a Custom Adaptor which uses a Data Handler that uses Dependency Injection. I have not been able to get me data handler instantiated in the custom handler. Get error like "There is no parameterless constructor for the custom adaptor".
How do I do this. I have spent a week trying to find a solution. All the examples and tutorials are to too simplistic to give an answer to my problem.
Hi John Groome,
We have created a simple sample based on your requirements to demonstrate how
to inject a data service into a CustomAdaptor. Please kindly refer to the
attached sample for your reference.
Note: After connecting the database we need to copy the path of the
database and change the connection string with the copied path in
OrderContext,.cs file based on the NORTHWND.MDF file in APP_Data folder.
|
@inject DataGridService data;
<SfGrid @ref="@Grid" TValue="Order" ID="Grid" AllowPaging="true" Toolbar="@(new List<string>() { "Add", "Edit","Update","Delete","Cancel" })" Height="315"> <SfDataManager AdaptorInstance="@typeof(CustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager> <GridEditSettings
AllowAdding="true" AllowDeleting="true" AllowEditing="true"
Mode="EditMode.Normal"></GridEditSettings> </SfGrid>
@code{ public class CustomAdaptor : DataAdaptor { public DataGridService data = new DataGridService();
public override object Read(DataManagerRequest dm, string? key = null) { IEnumerable<Order> DataSource = data.GetAllOrder().ToList();
if (dm.Search != null && dm.Search.Count > 0) { // Searching DataSource = DataOperations.PerformSearching(DataSource, dm.Search); } if (dm.Sorted != null && dm.Sorted.Count > 0) { // Sorting DataSource = DataOperations.PerformSorting(DataSource, dm.Sorted); } if (dm.Where != null && dm.Where.Count > 0) { // Filtering DataSource = DataOperations.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator); } int count = DataSource.Cast<Order>().Count(); if (dm.Skip != 0) { //Paging DataSource = DataOperations.PerformSkip(DataSource, dm.Skip); } if (dm.Take != 0) { DataSource = DataOperations.PerformTake(DataSource, dm.Take); } return dm.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource; }
public override object Insert(DataManager dataManager, object value, string key) { data.AddOrder((Order)value); return value; }
public override object Update(DataManager dataManager, object value, string keyField, string key) { data.UpdateOrder((Order)value); return value; } public override object Remove(DataManager dataManager, object value, string keyField, string key) {
var delData = data.GetAllOrder().Where(x => x.OrderID == (int)value).FirstOrDefault();
data.DeleteOrder((int)value); return delData!;
}
} |
Regards,
Prathap Senthil
I am sorry, but this does not work. My dataHandler has a constructor that requires a Class IAircraftTypes to be injected into the constructor. Normally this is handled by the Dependency Injection. When I use the above code I get a "There is no parameterless constructor for the custom adaptor" error. I seems that I would have to find another way to use the Custom Data Adaptor.
AircraftTypesHandler.cs
using AircraftMaintApp.Models.ViewModels;
using DataAccessLibrary;
using DataAccessLibrary.Models;
namespace AircraftMaintApp.Logic.Aircraft;
public class AircraftTypesHandler : IAircraftTypesHandler
{
private readonly IAircraftTypes _db;
public AircraftTypesHandler(IAircraftTypes db)
{
_db = db;
}
public async Task<List<AircraftType>> GetList(string order = "[Description]", bool activeonly = true)
{
List<AircraftType> result = new();
var types = await _db.GetList(order, activeonly);
foreach (var type in types)
{
AircraftType newrec = new();
newrec.Id = type.Id;
newrec.Description = type.Description;
newrec.Active = type.Active;
result.Add(newrec);
}
return result;
}
public async Task<AircraftType> InsertRecord(AircraftType data)
{
AircraftTypeModel newrec = new();
newrec.Description = data.Description;
newrec.Active = data.Active;
var result = await _db.InsertRecord(newrec);
if (result.Success)
{
data.Id = result.Identity;
}
return data;
}
public async Task<AircraftType> UpdateRecord(AircraftType data)
{
AircraftTypeModel newrec = new();
newrec.Id = data.Id;
newrec.Description = data.Description;
newrec.Active = data.Active;
var result = await _db.UpdateRecord(newrec);
if (!result.Success)
{
var oldrec = await _db.GetById(data.Id);
data.Description = oldrec.Description;
data.Active = oldrec.Active;
}
return data;
}
public async Task<bool> DeleteRecord(AircraftType data)
{
AircraftTypeModel newrec = new();
newrec.Id = data.Id;
newrec.Description = data.Description;
newrec.Active = data.Active;
var result = await _db.DeleteRecord(newrec);
return result.Success;
}
}
Based on your reported issue, we suggest the following solution if you want to inject some of your services into a Custom Adaptor and use the service. Initially, you need to add the CustomAdaptor class as AddScoped in the Program.cs file. To resolve this problem, kindly refer to the below code snippet and sample for your reference.
|
builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddSyncfusionBlazor(); builder.Services.AddScoped<CustomAdaptor>(); builder.Services.AddSingleton<OrderData>(); var app = builder.Build();
|
Thank you!
This has solved my problem.
Many thanks.
Thanks for the update,
We
are happy to hear that the provided solution was helpful. We are closing the
thread now.