mirror of
https://github.com/chsakell/aspnet-core-signalr-angular.git
synced 2025-12-22 09:17:47 +00:00
added Data, Models, EntityFramework
This commit is contained in:
@@ -5,27 +5,37 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR.Infrastructure;
|
||||
using LiveGameFeed.Hubs;
|
||||
using LiveGameFeed.Data.Abstract;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class FeedsController : ApiHubController<Broadcaster>
|
||||
{
|
||||
public FeedsController(IConnectionManager signalRConnectionManager)
|
||||
: base(signalRConnectionManager) { }
|
||||
|
||||
IFeedRepository _feedRepository;
|
||||
public FeedsController(
|
||||
IConnectionManager signalRConnectionManager,
|
||||
IFeedRepository feedRepository)
|
||||
: base(signalRConnectionManager)
|
||||
{
|
||||
_feedRepository = feedRepository;
|
||||
}
|
||||
|
||||
// GET api/values
|
||||
[HttpGet]
|
||||
public IEnumerable<string> Get()
|
||||
public IEnumerable<Feed> Get()
|
||||
{
|
||||
return new string[] { "value1", "value2" };
|
||||
IEnumerable<Feed> _feeds = _feedRepository.GetAll();
|
||||
|
||||
return _feeds;
|
||||
}
|
||||
|
||||
// GET api/values/5
|
||||
[HttpGet("{id}")]
|
||||
public string Get(int id)
|
||||
public Feed Get(int id)
|
||||
{
|
||||
return "value";
|
||||
return _feedRepository.GetSingle(id);
|
||||
}
|
||||
|
||||
// POST api/values
|
||||
|
||||
25
Data/Abstract/IEntityBaseRepository.cs
Normal file
25
Data/Abstract/IEntityBaseRepository.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq.Expressions;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data.Abstract
|
||||
{
|
||||
public interface IEntityBaseRepository<T> where T : class, IEntityBase, new()
|
||||
{
|
||||
IEnumerable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);
|
||||
IEnumerable<T> GetAll();
|
||||
int Count();
|
||||
T GetSingle(int id);
|
||||
T GetSingle(Expression<Func<T, bool>> predicate);
|
||||
T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties);
|
||||
IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
|
||||
void Add(T entity);
|
||||
void Update(T entity);
|
||||
void Delete(T entity);
|
||||
void DeleteWhere(Expression<Func<T, bool>> predicate);
|
||||
void Commit();
|
||||
}
|
||||
}
|
||||
13
Data/Abstract/IRepositories.cs
Normal file
13
Data/Abstract/IRepositories.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data.Abstract
|
||||
{
|
||||
public interface IMatchRepository : IEntityBaseRepository<Match> { }
|
||||
|
||||
public interface IFeedRepository : IEntityBaseRepository<Feed> { }
|
||||
|
||||
}
|
||||
36
Data/LiveGameContext.cs
Normal file
36
Data/LiveGameContext.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LiveGameFeed.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace LiveGameFeed.Data
|
||||
{
|
||||
public class LiveGameContext : DbContext
|
||||
{
|
||||
public DbSet<Match> Matches { get; set; }
|
||||
public DbSet<Feed> Feeds { get; set; }
|
||||
|
||||
public LiveGameContext(DbContextOptions options) : base(options) { }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
|
||||
{
|
||||
relationship.DeleteBehavior = DeleteBehavior.Restrict;
|
||||
}
|
||||
|
||||
modelBuilder.Entity<Match>()
|
||||
.ToTable("Match");
|
||||
|
||||
modelBuilder.Entity<Feed>()
|
||||
.ToTable("Feed");
|
||||
|
||||
modelBuilder.Entity<Feed>()
|
||||
.Property(f => f.MatchId)
|
||||
.IsRequired();
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Data/LiveGameDbInitializer.cs
Normal file
74
Data/LiveGameDbInitializer.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data
|
||||
{
|
||||
public class LiveGameDbInitializer
|
||||
{
|
||||
private static LiveGameContext context;
|
||||
public static void Initialize(IServiceProvider serviceProvider)
|
||||
{
|
||||
context = (LiveGameContext)serviceProvider.GetService(typeof(LiveGameContext));
|
||||
|
||||
InitializeSchedules();
|
||||
}
|
||||
|
||||
private static void InitializeSchedules()
|
||||
{
|
||||
if (!context.Matches.Any())
|
||||
{
|
||||
Match match_01 = new Match
|
||||
{
|
||||
Host = "Panathinaikos",
|
||||
Guest = "Olimpiakos",
|
||||
HostScore = 3,
|
||||
GuestScore = 1,
|
||||
MatchDate = DateTime.Now,
|
||||
League = "FootballLeauge",
|
||||
Feeds = new List<Feed>
|
||||
{
|
||||
new Feed()
|
||||
{
|
||||
Description = "Match started",
|
||||
MatchId = 1
|
||||
},
|
||||
new Feed()
|
||||
{
|
||||
Description = "Goal for Panathinaikos",
|
||||
MatchId = 1
|
||||
},
|
||||
}
|
||||
};
|
||||
Match match_02 = new Match
|
||||
{
|
||||
Host = "Real Madrit FC",
|
||||
Guest = "Barchelona",
|
||||
HostScore = 5,
|
||||
GuestScore = 3,
|
||||
MatchDate = DateTime.Now,
|
||||
League = "Spanish League",
|
||||
Feeds = new List<Feed>
|
||||
{
|
||||
new Feed()
|
||||
{
|
||||
Description = "Match started",
|
||||
MatchId = 2
|
||||
},
|
||||
new Feed()
|
||||
{
|
||||
Description = "Goal for Real Madrid",
|
||||
MatchId = 2
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
context.Matches.Add(match_01); context.Matches.Add(match_02);
|
||||
|
||||
context.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
Data/Repositories/EntityBaseRepository.cs
Normal file
102
Data/Repositories/EntityBaseRepository.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using LiveGameFeed.Data.Abstract;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data.Repositories
|
||||
{
|
||||
public class EntityBaseRepository<T> : IEntityBaseRepository<T>
|
||||
where T : class, IEntityBase, new()
|
||||
{
|
||||
|
||||
private LiveGameContext _context;
|
||||
|
||||
#region Properties
|
||||
public EntityBaseRepository(LiveGameContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
#endregion
|
||||
public virtual IEnumerable<T> GetAll()
|
||||
{
|
||||
return _context.Set<T>().AsEnumerable();
|
||||
}
|
||||
|
||||
public virtual int Count()
|
||||
{
|
||||
return _context.Set<T>().Count();
|
||||
}
|
||||
public virtual IEnumerable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
|
||||
{
|
||||
IQueryable<T> query = _context.Set<T>();
|
||||
foreach (var includeProperty in includeProperties)
|
||||
{
|
||||
query = query.Include(includeProperty);
|
||||
}
|
||||
return query.AsEnumerable();
|
||||
}
|
||||
|
||||
public T GetSingle(int id)
|
||||
{
|
||||
return _context.Set<T>().FirstOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
public T GetSingle(Expression<Func<T, bool>> predicate)
|
||||
{
|
||||
return _context.Set<T>().FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
|
||||
{
|
||||
IQueryable<T> query = _context.Set<T>();
|
||||
foreach (var includeProperty in includeProperties)
|
||||
{
|
||||
query = query.Include(includeProperty);
|
||||
}
|
||||
|
||||
return query.Where(predicate).FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
|
||||
{
|
||||
return _context.Set<T>().Where(predicate);
|
||||
}
|
||||
|
||||
public virtual void Add(T entity)
|
||||
{
|
||||
EntityEntry dbEntityEntry = _context.Entry<T>(entity);
|
||||
_context.Set<T>().Add(entity);
|
||||
}
|
||||
|
||||
public virtual void Update(T entity)
|
||||
{
|
||||
EntityEntry dbEntityEntry = _context.Entry<T>(entity);
|
||||
dbEntityEntry.State = EntityState.Modified;
|
||||
}
|
||||
public virtual void Delete(T entity)
|
||||
{
|
||||
EntityEntry dbEntityEntry = _context.Entry<T>(entity);
|
||||
dbEntityEntry.State = EntityState.Deleted;
|
||||
}
|
||||
|
||||
public virtual void DeleteWhere(Expression<Func<T, bool>> predicate)
|
||||
{
|
||||
IEnumerable<T> entities = _context.Set<T>().Where(predicate);
|
||||
|
||||
foreach(var entity in entities)
|
||||
{
|
||||
_context.Entry<T>(entity).State = EntityState.Deleted;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Commit()
|
||||
{
|
||||
_context.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Data/Repositories/FeedRepository.cs
Normal file
12
Data/Repositories/FeedRepository.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using LiveGameFeed.Data.Abstract;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data.Repositories
|
||||
{
|
||||
public class FeedRepository : EntityBaseRepository<Feed>, IFeedRepository
|
||||
{
|
||||
public FeedRepository(LiveGameContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
12
Data/Repositories/MatchRepository.cs
Normal file
12
Data/Repositories/MatchRepository.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using LiveGameFeed.Data.Abstract;
|
||||
using LiveGameFeed.Models;
|
||||
|
||||
namespace LiveGameFeed.Data.Repositories
|
||||
{
|
||||
public class MatchRepository : EntityBaseRepository<Match>, IMatchRepository
|
||||
{
|
||||
public MatchRepository(LiveGameContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
13
Models/Feed.cs
Normal file
13
Models/Feed.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace LiveGameFeed.Models
|
||||
{
|
||||
public class Feed : IEntityBase
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public int MatchId { get; set; }
|
||||
public Match Match { get; set; }
|
||||
}
|
||||
}
|
||||
12
Models/IEntityBase.cs
Normal file
12
Models/IEntityBase.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LiveGameFeed.Models
|
||||
{
|
||||
public interface IEntityBase
|
||||
{
|
||||
int Id { get; set; }
|
||||
}
|
||||
}
|
||||
22
Models/Match.cs
Normal file
22
Models/Match.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LiveGameFeed.Models
|
||||
{
|
||||
public class Match : IEntityBase
|
||||
{
|
||||
public Match()
|
||||
{
|
||||
Feeds = new List<Feed>();
|
||||
}
|
||||
public int Id { get; set; }
|
||||
public string Host { get; set; }
|
||||
public string Guest { get; set; }
|
||||
public int HostScore { get; set; }
|
||||
public int GuestScore { get; set; }
|
||||
public DateTime MatchDate { get; set; }
|
||||
public string League { get; set; }
|
||||
|
||||
public ICollection<Feed> Feeds { get; set; }
|
||||
}
|
||||
}
|
||||
12
Startup.cs
12
Startup.cs
@@ -2,8 +2,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LiveGameFeed.Data;
|
||||
using LiveGameFeed.Data.Repositories;
|
||||
using LiveGameFeed.Data.Abstract;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -27,6 +31,12 @@ namespace LiveGameFeed
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<LiveGameContext>(options => options.UseInMemoryDatabase());
|
||||
|
||||
// Repositories
|
||||
services.AddScoped<IMatchRepository, MatchRepository>();
|
||||
services.AddScoped<IFeedRepository, FeedRepository>();
|
||||
|
||||
// Add framework services.
|
||||
services.AddMvc();
|
||||
|
||||
@@ -61,6 +71,8 @@ namespace LiveGameFeed
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
app.UseSignalR();
|
||||
|
||||
LiveGameDbInitializer.Initialize(app.ApplicationServices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { FeedService, ConnectionState } from './shared/feed.service'
|
||||
import { FeedService } from './shared/feed.service';
|
||||
import { ConnectionState } from './shared/interfaces';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { FeedService, ConnectionState } from '../shared/feed.service';
|
||||
import { FeedService } from '../shared/feed.service';
|
||||
import { ConnectionState } from '../shared/interfaces';
|
||||
|
||||
@Component({
|
||||
selector: 'home',
|
||||
|
||||
@@ -5,25 +5,7 @@ import 'rxjs/add/operator/toPromise';
|
||||
import { Observable } from "rxjs/Observable";
|
||||
import { Subject } from "rxjs/Subject";
|
||||
|
||||
interface FeedSignalR extends SignalR {
|
||||
broadcaster: FeedProxy
|
||||
}
|
||||
|
||||
interface FeedProxy {
|
||||
client: FeedClient
|
||||
}
|
||||
|
||||
interface FeedClient {
|
||||
userConnected: (user: any) => void;
|
||||
userDisconnected: (id: string) => void;
|
||||
messageReceived: (message: string) => void;
|
||||
}
|
||||
|
||||
export enum ConnectionState {
|
||||
Connected = 1,
|
||||
Disconnected = 2,
|
||||
Error = 3
|
||||
}
|
||||
import { FeedSignalR, FeedProxy, FeedClient, ConnectionState } from './interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class FeedService {
|
||||
|
||||
20
app/shared/interfaces.ts
Normal file
20
app/shared/interfaces.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/* SignalR related interfaces */
|
||||
export interface FeedSignalR extends SignalR {
|
||||
broadcaster: FeedProxy
|
||||
}
|
||||
|
||||
export interface FeedProxy {
|
||||
client: FeedClient
|
||||
}
|
||||
|
||||
export interface FeedClient {
|
||||
userConnected: (user: any) => void;
|
||||
userDisconnected: (id: string) => void;
|
||||
messageReceived: (message: string) => void;
|
||||
}
|
||||
|
||||
export enum ConnectionState {
|
||||
Connected = 1,
|
||||
Disconnected = 2,
|
||||
Error = 3
|
||||
}
|
||||
@@ -11,6 +11,9 @@
|
||||
"Microsoft.AspNetCore.SignalR.Server": "0.2.0-*",
|
||||
"Microsoft.AspNetCore.StaticFiles": "1.1.0-*",
|
||||
"Microsoft.AspNetCore.WebSockets": "0.2.0-*",
|
||||
"Microsoft.EntityFrameworkCore": "1.0.1",
|
||||
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "1.0.1",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
|
||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
||||
|
||||
Reference in New Issue
Block a user