I have a base controller:
Public MustInherit Class InjuredWorkerController(Of TManager As IInjuredWorkerManagerBase)
Then I have a home controller:
Public Class HomeController
Inherits InjuredWorkerController(Of IInjuredWorkerManager)
IInjuredWorkerManager inherits IInjuredWorkerManagerBase
Why does this throw a cast exception:
Dim manager = CType(filterContext.Controller, InjuredWorkerController(Of IInjuredWorkerManagerBase)).Manager
Unable to cast object of type 'MyClaim.Controllers.HomeController' to type 'MyClaim.Controllers.InjuredWorkerController`1[SAIF.Web.Mvc.MyClaim.IInjuredWorkerManagerBase]'.
You need to extract an interface for your InjuredWorkerController to make it work, since co- and contravariance only works with interfaces and delegates.
This code compiles and runs (C# console app, I'm not fluent in VB.Net...):
using System;
namespace TestApplication
{
public interface IInjuredWorkerController<out TManager>
where TManager : IInjuredWorkerManagerBase
{
TManager Manager { get; }
}
public abstract class InjuredWorkerController<TManager>
: IInjuredWorkerController<TManager>
where TManager : IInjuredWorkerManagerBase, new()
{
protected InjuredWorkerController()
{
Manager = new TManager();
}
public TManager Manager { get; private set; }
}
public interface IInjuredWorkerManagerBase
{
string Name { get; }
}
public interface IInjuredWorkerManager
: IInjuredWorkerManagerBase {}
public class InjuredWorkerManager : IInjuredWorkerManager
{
public string Name
{
get { return "Homer"; }
}
}
public class HomeController
: InjuredWorkerController<InjuredWorkerManager> {}
internal class Program
{
private static void Main()
{
var controller = new HomeController();
var manager = ((IInjuredWorkerController<IInjuredWorkerManagerBase>)controller).Manager;
Console.Out.WriteLine(manager.Name);
Console.ReadKey();
}
}
}
Eric Lippert's blog series on the subject is a must read.
Related
i want to apply command Design pattern with dependency Injection in the following situation: i have three types of reports in my system (SubscriptionReport, SalesReport, SpechialistReport) so i created one interface IReportService
public interface IReportService<T> where T: class
{
public Task<GenericResponse<List<T>>> GetReport(string searchKey, DateTime from, DateTime to);
}
and to apply OCP i have implemented the GetReport function tree times for (SubscriptionReport, SalesReport, SpechialistReport)
public class SpechialistReportService : IReportService<SpechialistReportDTO>
{
public Task<GenericResponse<List<SpechialistReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
public class SubscriptionReportService : IReportService<SubscriptionReportDTO>
{
public Task<GenericResponse<List<SubscriptionReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
public class SalesReportService : IReportService<SalesReportDTO>
{
public Task<GenericResponse<List<SalesReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
after that i have added the dependency
services.AddScoped(typeof(IReportService<SpechialistReportDTO>), typeof(SpechialistReportService));
services.AddScoped(typeof(IReportService<SubscriptionReportDTO>), typeof(SubscriptionReportService));
services.AddScoped(typeof(IReportService<SalesReportDTO>), typeof(SalesReportService));
the problem is in calling the dependency in the controller constructor
private readonly IEnumerable<IReportService> _reportService; // Should be IReportService<dont know what class should i specify here>
public ReportController(IReportService<T> reportService)
{
this._reportService = reportService;
}
Any help would be appreciated thanks in advance,
Okay i solved this problem by removing the Generic and adding marker interface to the DTOs classes
public interface ReportRoot
{
}
public class SubscriptionReportDTO : ReportRoot
{
// Some data here
}
public class SalesReportDTO: ReportRoot
{
// Some data here
}
In ReportService Interface
public interface IReportService
{
public Task<GenericResponse<List<ReportRoot>>> Report();
}
public class SubscriptionReportService : IReportService {
public async Task<GenericResponse<List<ReportRoot>>> Report()
{
List<ReportRoot> subscriptionReportDTO = new List<ReportRoot>();
SubscriptionReportDTO test = new SubscriptionReportDTO();
test.SalesTax = "1000";
subscriptionReportDTO.Add(test);
return new GenericResponse<List<ReportRoot>>("1", subscriptionReportDTO.Count, "Success", subscriptionReportDTO);
}
}
public class SalesReportService : IReportService {
public async Task<GenericResponse<List<ReportRoot>>> Report()
{
List<ReportRoot> salesReportDTO = new List<ReportRoot>();
SalesReportDTO test = new SalesReportDTO ();
test.SalesTax = "1000";
salesReportDTO .Add(test);
return new GenericResponse<List<ReportRoot>>("1", salesReportDTO.Count, "Success", salesReportDTO );
}
}
In controller
private readonly IEnumerable<IReportService> _reportService;
public ReportController(IEnumerable<IReportService> reportService)
{
this._reportService = reportService;
}
I have a scenario wherein I have multiple connection strings defined under appsettings.json like this:
"ConnectionString": {
"ConnectionZone1": "Server=(localdb)\\mssqllocaldb;Database=Blogging;Trusted_Connection=True;",
"ConnectionZone2": "Server=localhost;Database=Blogging;Trusted_Connection=True;"
},
This I have registered in my startup.cs file as well:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DbContextZone1>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionZone1")));
services.AddDbContext<DbContextZone2>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionZone2")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
I have created Model and context classes using database first approach, and registered my context classes as follows:
public partial class BloggingContext : DbContext
{
public BloggingContext()
{
}
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{
}
public virtual DbSet<Blog> Blog { get; set; }
public virtual DbSet<Post> Post { get; set; }
and created two other context classes which inherits from the above main base class:
public class DbContextZone1 : BloggingContext
{
public DbContextZone1()
{
}
}
public class DbContextZone2 : BloggingContext
{
public DbContextZone2()
{
}
}
Now I have created my API controllers and am trying to call these context methods.
[HttpGet]
public async Task<ActionResult<IEnumerable<object>>> GetItems()
{
if (alternate)
{
alternate = false;
using (var context = new DbContextZone1())
{
return await context.Blog.ToListAsync();
}
}
using(var context = new DbContextZone2())
{
return await context.Post.ToListAsync();
}
}
The issue is when I run my application it throws error that my context class should have parameterized constructor in order to pass options.
So in the DbContextZone1 and DbContextZone2 constructor which context options parameter will come?. I tried putting like this, but it never works and throws error when I call the API controller:
public class DbContextZone1 : BloggingContext
{
public DbContextZone1(DbContextOptions<BloggingContext> options)
: base(options)
{
}
}
public class DbContextZone2 : BloggingContext
{
public DbContextZone2(DbContextOptions<BloggingContext> options)
: base(options)
{
}
}
And this the error:
So any help or code ideas or suggestions in how to achieve multiple connections or make my code right?.
From your appsettings.json,it seems that you want to connect to the same database in different server.You are no need to create a base DbContext,just inherits default DbContext like below:
public class DbContextZone1 : DbContext
{
public DbContextZone1(DbContextOptions<DbContextZone1> options)
: base(options)
{
}
public virtual DbSet<Blog> Blog { get; set; }
}
public class DbContextZone2 :DbContext
{
public DbContextZone2(DbContextOptions<DbContextZone2> options)
: base(options)
{
}
public virtual DbSet<Post> Post { get; set; }
}
And call the API Controller like below:
private readonly DbContextZone1 _context1;
private readonly DbContextZone2 _context2;
public ABCController(DbContextZone1 context1, DbContextZone2 context2)
{
_context1 = context1;
_context2 = context2;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<object>>> GetItems()
{
//....
if (alternate)
{
alternate = false;
return await _context1.Blog.ToListAsync();
}
return await _context2.Post.ToListAsync();
}
Change Your DbContext Cunstructors to this:
public class DbContextZone1 : BloggingContext
{
public DbContextZone1(DbContextOptions<DbContextZone1> options)
: base(options)
{
}
}
public class DbContextZone2 : BloggingContext
{
public DbContextZone2(DbContextOptions<DbContextZone2> options)
: base(options)
{
}
}
Update:
If you've got errors after changing your DbContext class is because you're trying to access default constructors like below:
using (var context = new DbContextZone1())
when there is no implemented default constructor in your classes. As you've registered your DbContext classes in .net core DI system, you just need to inject DbContextZone1 and DbContextZone2 in Controller's constructor, and then you can easily access to contexts. But before doing that you should add your DbSet to DbContext classes and change them to:
public class DbContextZone1 : BloggingContext
{
public DbContextZone1(DbContextOptions<DbContextZone1> options)
: base(options)
{ }
public virtual DbSet<Blog> Blogs { get; set;}
}
public class DbContextZone2 : BloggingContext
{
public DbContextZone2(DbContextOptions<DbContextZone2> options)
: base(options)
{ }
public virtual DbSet<Post> Posts { get; set;}
}
Note: You can keep your DbSets in BloggingContext and then access them via _context in your controller but moving them like above makes your contexts isolated and gives single responsibility to the Contexts.
Now your Controller should be like this:
private readonly DbContextZone1 _context1;
private readonly DbContextZone2 _context2;
public MyController(DbContextZone1 context1, DbContextZone2 context2)
{
_context1 = context1;
_context2 = context2;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<object>>> GetItems()
{
if (alternate)
{
alternate = false;
return await _context1.Blogs.ToListAsync();
}
return await _context2.Posts.ToListAsync();
}
Public class is not working in wcf services. I have created one another public class and use into my service.svc but class is not accessible. Please see the following code.
ITest.cs
namespace TestProject.Services
{
[ServiceContract]
public interface ITest
{
[ServiceContract]
public interface ITest
{
[OperationContract]
DataTable SelectData(string sSectionName);
}
}
}
ITest.svc.cs
namespace TestProject.Services
{
public class Test: ITest
{
public DataTable SelectData(string sSectionName)
{
//do some work
}
}
}
Ohter New class
Public class connection
{
public int sum(int i, int b)
{
return i+b;
}
}
My connection class is not accessible in ITest.svc.cs. Please help
Try rewriting connection as such:
namespace TestProject.Services
{
Public class connection
{
public int sum(int i, int b)
{
return i+b;
}
}
}
I am new to ASP.NET and very new to EF. I am trying to develop an application and after reading some sites I've decided I'm going to create a 3-tier application (DAL, BL, a website as the frontend).
For the DAL layer I've taken inspiration from here
http://codefizzle.wordpress.com/2012/07/26/correct-use-of-repository-and-unit-of-work-patterns-in-asp-net-mvc/
public interface IGenericRepository<T> where T : class
{
void Add(T a);
}
public interface IUnitOfWork:IDisposable
{
IGenericRepository<UserInfo> UserInfoRepository { get; }
void Commit();
}
public class EfGenericRepository<T> : IGenericRepository<T> where T : class
{
private DbSet<T> _dbSet;
public EfGenericRepository(DbSet<T> dbSet)
{
_dbSet = dbSet;
}
public void Add(T a)
{
_dbSet.Add(a);
}
}
public class EfUnitOfWork : DbContext, IUnitOfWork
{
private readonly EfGenericRepository<UserInfo> _userInfoRepo;
public DbSet<UserInfo> UserInfos { get; set; }
public EfUnitOfWork()
{
_userInfoRepo = new EfGenericRepository<UserInfo>(UserInfos);
}
public IGenericRepository<UserInfo> UserInfoRepository
{
get { return _userInfoRepo; }
}
public void Commit()
{
this.SaveChanges();
}
}
and my BL looks like this:
public interface IBussinessLogic
{
void AddUserInfo(string c);
}
public class BusinessLogic: IBussinessLogic
{
private IUnitOfWork _unitOfWork;
public BusinessLogic()
{
_unitOfWork = new EfUnitOfWork();
}
public void AddUserInfo(string c)
{
_unitOfWork.UserInfoRepository.Add(new UserInfo()
{
Address = c
});
_unitOfWork.Commit();
}
}
Now I am using web-forms but I don't think that should be an issue.
On click i execute this:
IBussinessLogic businessLogic = new BusinessLogic();
businessLogic.AddUserInfo(address.Text);
But nothing happens,my data is not saved in the db.
Can anyone please help me?
UPDATE: I completely reformulated the question
I am trying to implement an algorithm that would change the class name dynamically.
For Example:
Data.cs
public class Data
{
public string text1 { get; set; }
public string text2 { get; set; }
}
User1.ascx
public partial class User1 : System.Web.UI.UserControl
{
public Data datas = new Data();
}
User2.ascx
public partial class User2 : System.Web.UI.UserControl
{
public Data datas = new Data();
}
User.aspx
public partial class User: System.Web.UI.Page
{
[WebMethod]
public static string RequestUC(Data datas)
{
if (datas.userfile = "User1.ascx")
{
User1 userControl = (User1)page.LoadControl(datas.userfile);
}
else
{
User2 userControl = (User2)page.LoadControl(datas.userfile);
}
using (Page page = new Page())
{
userControl.datas = datas; // the error says that the userControl not recognized
page.Controls.Add(userControl);
using (StringWriter writer = new StringWriter())
{
page.Controls.Add(userControl);
HttpContext.Current.Server.Execute(page, writer, false);
return writer.ToString();
}
}
}
}
The problem is I can't get the User.aspx work. Any solutions would work.
How can I use generics in this case?
thank YOU
Use inheritance.
Create a base user control class:
public abstract class UserControlBase : System.Web.UI.UserControl {
public abstract Data Datas { get; set; }
}
Then derive each user control from that class (and implement the abstract properties, not shown):
public partial class User1 : UserControlBase
public partial class User2 : UserControlBase
And in your web method:
//TODO - validate that datas.userfile is appropriate
UserControlBase myControl = page.LoadControl(datas.userfile);