I am stating to look into the Domain Events pattern and have read a lot of resources on the subject but I cannot find a good way of implementing for our requirements. Basically we have a Service/Domain layer which wraps the repository layer for reads/writes with a simplistic CQRS implementation. We have an ASP.NET Mvc application which consumes this service/domain layer. The whole application is tied together with Autofac and what I would like to happen is for the following:
When a news item is created by calling say "CreateNews" on the service layer register that an event will need to be raised as so:
public void CreateNews(Domain.Entities.News.NewsBO news)
{
ValidateBusinessObject(news);
var entityNews = AutoMapper.Mapper.Map<Repositories.Entities.News.News>(news);
NewsCommandRepository.Create(entityNews);
_domainEventManager.Register<NewsCreatedDomainEvent>(x => x.News = news);
}
This is all happening in a transaction and I don't want to actually raise the event until the save is completed so in our save changes method I want to do this:
public void SaveChanges()
{
_repoCommandManager.SaveChanges();
_domainEventManager.RaiseEvents();
}
Then in our ASP.NET Mvc application I want to have an implementation of an IHandler which looks like this:
public class NewsCreatedDomainEventCacheHandler : IHandles<Project.Services.Domain.Events.News.NewsCreatedDomainEvent>
{
public void Handle(Services.Domain.Events.News.NewsCreatedDomainEvent #event)
{
// In here we would update the cache or something else particular to the web layer
}
}
I cannot figure out how to go about raising this event from the save method and calling the implementation in the Web.Mvc application.
Any suggestions would be appreciated.
I think I have an example of how to do this for you and I happen to be using MVC and AutoFac also! In my specific example I am concentrating on Command/Query separation but in doing so I had to implement a domain event pattern.
First have a read of this blog post so you get an overview of how things hang together and what the code looks like:
http://www.nootn.com.au/2013/03/command-query-separation-to-better.html
So I would recommend installing the DotNetAppStarterKit.Web.Mvc NuGet package, then take a look at the Global.asax file for how to register all the components you will need. You can peruse the SampleMvc application for things like Event Subscribers.
I hope this helps and gets you up and going quickly. You can just use the event publisher/subscriber parts of DotNetAppStarterKit without using commands and queries.
Related
So recently I started a project with Ardalis Clean Architecture as template it was all nice but when signalR came into my project i can't figure it. I'm trying to inject interface that my hub implements and call it's method, but everytime when it's called it throws NullReferenceException, it seems like all of the signalR components are null within this injected interface. Registered all hubs and registered it's interfaces using AutoFac. Trying to avoid situation when I'm forced to reference signalR package within core layer.
Core layer:
public class UpdateTimerNotificationHandler : INotificationHandler<UpdateTimerNotification>
{
private readonly ITimerHub _timerHub;
public UpdateTimerNotificationHandler(ITimerHub timerHub)
{
_timerHub = timerHub;
}
public Task Handle(UpdateTimerNotification notification, CancellationToken cancellationToken)
{
return _timerHub.UpdateTimerAsync(notification);
}
}
public interface ITimerHub
{
Task UpdateTimerAsync(UpdateTimerNotification updateTimerNotification);
}
Infrastructure layer:
public class TimerHub : Microsoft.AspNetCore.SignalR.Hub, ITimerHub
{
private readonly IAccountRepository _accountRepository;
public TimerHub(IAccountRepository accountRepository)
{
_accountRepository = accountRepository;
}
public Task UpdateTimerAsync(UpdateTimerNotification updateTimerNotification)
{
return Clients.All.SendAsync("UpdateTimer", updateTimerNotification);
}
}
private void RegisterHubs(ContainerBuilder builder)
{
foreach (var assembly in _assemblies)
{
builder.RegisterHubs(assembly);
}
builder.RegisterType<TimerHub>().As<ITimerHub>();
}
Web layer:
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule(new DefaultCoreModule());
containerBuilder.RegisterModule(
new DefaultInfrastructureModule(builder.Environment.EnvironmentName == "Development"));
});
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
var app = builder.Build();
GlobalHost.DependencyResolver = new AutofacDependencyResolver(app.Services.GetAutofacRoot());
I was trying manually registering hubs with no luck, still same issue
The good news is SignalR already implements IHubContext<T> In your case you don't need to inject ITimerHub interface. If your TimerHub Already Implements ITimerHub that's good enough In your case it would look like this
public class HomeController : Controller
{
private readonly IHubContext<TimerHub> _hubContext;
public HomeController(IHubContext<TimerHub> hubContext)
{
_hubContext = hubContext;
}
}
Also you didn't show your startup.cs class.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSignalR();
...
}
and
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.MapHub<TimerHub>("/yourEndPointGoesHere");
}
If you really wanted to, which I don't recommend is [look at it here][1]
There is an example on using IHubContext in generic code.
I understand you're trying to learn something new. And yes, it's important to decouple application so you're headed in the right direction in what you want to achieve. However I wouldn't recommend this approach you are taking. His approach doesn't apply to 99% of the projects out there. Let me explain my point of view. Don't get pulled in by the buzz words in his videos and blogs. It's important to understand that these principals are SUBJECTIVE to your application.
You don't have 15,000 classes, services, views, and N Layers etc... in your app.
You don't need the flexibility of a domain driven approach. I've seen massive and I mean massive projects, ones that are 25 years old and have millions of lines of code. Let me tell you you're not swapping out your data layer all willy nilly like he makes it seem to be. On a big project there is no "it makes it easy" way to do that. Putting it in Repos and a data access layer doesn't really help. You can put in a data access layer, or in your services. You still need to test out 150,000 lines of code. The only time it's been useful for me is when I've had 4 data sources all having a getBy... function that needs to aggregate info from 4 sources. You don't need it for unit testing either. Just create a mock variable in your unit tests no need to mock your db connection. I find it more useful to have your unit tests actually hooked up to a database even though it's a dependency, it's actually useful.
He said it himself "You can go with a minimalist API and work your way up from there" Which is what you should do. What's the point of SOLID and Repos in a project with no code? For example the I in solid is implementation of interfaces. Interfaces do 2 things -
A. Tell your application what it should and shouldn't do. so, what are you enforcing that could break or needs this kind of abstraction?
B. Decouple the application. Where do you have 3+ different classes being injected in one piece of code with the same DoSomething() based on the type?
He touches over other things that only apply when you have 500 different things going on, and his case it's still overkill.
If you want to break it up you can take a simple approach.
-MainApiProject
-ServicesProject (you can also put interfaces in here)
-InterfacesProject(if you need them between multiple projects and have a lot of them)
-UtilitiesProject
Then look at what he's doing and if you see you need it take it.
I can go on but this is getting long as is.
[1]: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-6.0
I am doing a course of MVVM for Xamarin Forms, and the teacher in one class used FreshIOC.Container.Register to "register different instances or dependencies", and I don't understand how that affects my code, if someone can explain it I would appreciate it.
My code as an example:
public App()
{
InitializeComponent();
FreshIOC.Container.Register<IContactService,ContactService>();
FreshIOC.Container.Register<IUserDialogs>(UserDialogs.Instance);
}
class MainViewModel : FreshBasePageModel
{
private IContactService service;
private IUserDialogs dialog;
public MainViewModel(IContactService Service, IUserDialogs Dialog)
{
service = Service;
dialog = Dialog;
}
public override async void Init(object initData)
{
dialog.ShowLoading();
var tempt = await service.GetData();
Contacts = tempt;
dialog.HideLoading();
}
}
I don't see what FreshIOC.Container.Register does, or how it connects to the MainViewModel class. By the way, there is another method called "Resolve" instead of "Register", If you could also explain that one I would appreciate it.
That is all, if you need anything more from my code I will provide it as soon as I see your request, thank you all so much for your time, have a nice day.
The Register registers your concrete classes at the IoC framework.
So, IoC in short will work like this:
Instead of making new ContactService all the time, you'll ask the IoC framework to give you one.
This has some benifits;
because you often register by interface, you only need to worry about the ContractService constructor at one place, and not all over the place.
it makes your code better testable because the consuming page is not responsible for creating the service. This might sound a bit mystic, but if you write unit test, you'll immediate see the benefits.
what does Register do?
It makes sure you can request this service from the IoC framework.
The first one registers the ContactService as an IContactService; so, if you request an IContactService you'll get the registered type.
The second one registers the instance of a type: if you request it, you'll always get that instance. Works well for settings and thread safe stuff. Works not at all for database related things.
What does Resolve do?
It enables you to retrieve a service from the IoC framework, but note: there might be better ways e.g. by constructor injection.
This code is an example of constructor injection: by registering the IContactService you've enabled the possibility to resolve the service automatically. If you ommit the registration this is not possible:
public MainViewModel(IContactService Service, IUserDialogs Dialog)
{
service = Service;
dialog = Dialog;
}
If you didnt use the IoC framework, you would have ended up with new ContactService in every model you where using, which can be considered as an antipattern for such services, because;
changing the implementation concrete type will result in a lot of code changes.
changing the constructor would lead to a lot of code changes
unittesting the consumer causes an instantation of the service, which can lead to side effects.
I have implemented a Windows service which is to get a list of emails from the database and send them using .net mail every 60 seconds.
I have designed it using repository pattern, please see the screenshot of the solution folders and projects.Click to see the picture
Questions:
In terms of the pattern am I on the right track? structure of the separated projects, creating an interface for each repository and a service per repository.
If some of the business logics have nothing to do with the database, do I still need to create a repository for them or a service is enough?
I have a SMTP service class which is implementing .net mail and sending emails, while I'm sending each email I need to update the database, I would like to know if putting the update logic in the SMTP Service class is a good practice? It's something like below
public class SMTPService : ISMTPService
{
SmtpClient client;
MailMessage newMessage;
EmailService emailService;
IEventLoggerService MailCheckerLog;
public async Task SendEmail(tb_Email email)
{...}
void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e, tb_Email email)
{
if (e.Cancelled)
{
}
if (e.Error != null)
{
}
else
{
email.DateSent = DateTime.Now;
emailService.Update(email);
}
client.Dispose();
newMessage.Dispose();
}
}
I'm not sure what you'd like to achieve exactly and what business requirements you have.
The structure is OK for now, but consider this: you have a user entity and a photo entity. Each user must have a photo associated with them. How would you handle that scenario?
You have to create a UserRepository and a PhotoRepository. Of couse you first have to insert the user record in order for the photo record to reference it later.
So you call the Insert() method of the UserRepository. When the user is inserted, you call the Insert() method of the PhotoRepository. But what if that Insert() fails? Now you have a user in the db who doesn't have a photo.
You have to insert the user and the photo together, in one transaction. That's where the unit of work pattern comes in. You have to use that if you have business logic that concerns more than one entity type. If all you do is handle emails, then this is fine. If not, you have to add that pattern to your application. See an example here.
A service, again, is something that handles business transactions, and a business transaction can touch multiple types of entites. Again, the unit-of-work pattern can help you with this. But usually repositories are created based on your entites, and services based on your business logic. In the example, you could have a UserService that uses both the UserRepository and the PhotoRepository (usually through the unit of work).
In case of sending the e-mails, I would again design the services based on my business logic. And probably the business logic is to 'send e-mails', not to 'send e-mails via SMTP'. What happens if you decide to use a service like SendGrid? Then it is not SMTPService anymore.
I would probably create an EmailService (which you also have), and this would have a SendEmails() method. This would use the EmailRepository to fetch the emails, send it using SMTP, then update it and save it through the unit-of-work.
Or, if you want to be really abstract, you can create an IEmailSenderService interface with one method, SendEmail(Email email). Then you can create an SmtpEmailSenderService, which implements this interface and wraps the SmtpClient class and sends the email using SMTP. If you decide to move to SendGrid, you can create a SendGridEmailSenderService, that uses HttpClient to issue requests to SendGrid. The update is still done in the EmailService using the repository and the unit of work, but now the EmailService itself does not use SmtpClient but simply the IEmailSenderService interface.
I have searched a lot for MVP, but I haven't found any good articles that help me understand it very well. Does anyone know of any good articles on the subject, with real-world examples to help me understand it better?
Thanks in advance.
Check out my answer to a so post, which may help you:
Is ASP.net Model View Presenter worth the time?
It goes through the differences between MVP and MVC, as often the two are contrasted.
Also, there's some helpful links, which show how to easily fit an MVP model to an existing ASP.Net website.
HTH
Here's a site devoted to doing mvp on asp.net: http://webformsmvp.com/
MVP as a pattern is kinda obsolete - MVC (which has a great asp.net framework and support) and MVVM (the de facto pattern of WPF) have largely taken over. In fact, Martin Fowler (MVP's inventor) has documented that the pattern really ought to be split into two patterns, Passive View and Supervising Controller on his site: http://martinfowler.com/eaaDev/ModelViewPresenter.html
ASP.NET Supervising Controller (Model View Presenter) From Schematic To Unit Tests to Code
Simplest example of MVP design patter of Asp.net
Model View Presenter with ASP.NET
Very Quick MVP Pattern to Use with ASP.NET
Edited
One more link:
Model View Presenter (MVP) Design Pattern with .NET - Winforms vs. ASP.NET Webforms
If you would like to dig more into this patter, take a look at the Web Client Software Factory 2010 tool.
This tool is basically used to create composite web applications (modules) but the views are implemented using the MVP pattern. If you are going to maintain traditional ASP.Net code or if you want to dig a little bit more in the ASP.Net paradigm, checking the source code of this tool is a great place to start.
This tool requires you to install a couple of extensions to Visual Studio, and after that, you can create a special web project that will implement the MVP for you, it will add contextual menus to Visual Studio to facilitate the tasks
Example:
Create a new project
Add a view with a presenter
Check the generated files
Check the default generated code:
public partial class MyNewView : Microsoft.Practices.CompositeWeb.Web.UI.Page, IMyNewViewView
{
private MyNewViewPresenter _presenter;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this._presenter.OnViewInitialized();
}
this._presenter.OnViewLoaded();
}
[CreateNew]
public MyNewViewPresenter Presenter
{
get
{
return this._presenter;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
this._presenter = value;
this._presenter.View = this;
}
}
// TODO: Forward events to the presenter and show state to the user.
// For examples of this, see the View-Presenter (with Application Controller) QuickStart:
//
}
public interface IMyNewViewView
{
}
public class MyNewViewPresenter : Presenter<IMyNewViewView>
{
// NOTE: Uncomment the following code if you want ObjectBuilder to inject the module controller
// The code will not work in the Shell module, as a module controller is not created by default
//
// private IShellController _controller;
// public MyNewViewPresenter([CreateNew] IShellController controller)
// {
// _controller = controller;
// }
public override void OnViewLoaded()
{
// TODO: Implement code that will be executed every time the view loads
}
public override void OnViewInitialized()
{
// TODO: Implement code that will be executed the first time the view loads
}
// TODO: Handle other view events and set state in the view
}
Take a loot at the tool:
http://webclientguidance.codeplex.com/wikipage?title=Web%20Client%20Software%20Factory&referringTitle=Home
http://msdn.microsoft.com/en-us/library/ff648752.aspx
BTW, If you are going to start a new project, it should be a better idea to use the MVC, if you need to redactor an existing application, you can take as a base the implementation of the MVP in the Web Client Software Factory.
If you are interested, I think there's a work-through in order to convert an existing application to use the Web Client Software Factory
I was working on an application that makes quite a few requests using the HttpWebRequest class to bring back data from the web. Now my app makes nearly identical calls in multiple parts of my application. This is turning into a problem because I'm duplicating a lot of code.
The ideal solution would be to encapsulate the logic that makes the calls to the web in it's own class that way updating is a breeze and it can be reused throughout my application. I'm just not sure how to make an asynchronous call in a separate class and return the value to my main code behind so I can update the UI with the data.
Can someone provide me with some guidance on how to make this happen? I know this has to be possible because developers are doing it all the time when following the MVVM pattern.
I'm using Silverlight/C#.
We have code like this in our Silverlight app for use with WCF Data Services. You could probably do something similar for your web requests:
Here is some sample code (untested) (note that I have not actually ever written any code that does web requests, but maybe the async pattern is similar to other stuff that I have done in Silverlight):
public class WebRequesterHelper
{
Action _callback;
public void MakeWebRequest(object whateverYouNeedForTheWebRequest, Action callback)
{
_callback = callback;
//Make your async web request here, passing the helper object's callback.
IAsyncResult result = yourWebRequestObject.BeginGetResponse(new AsyncResultCallback(WebRequestCallback), yourRequestState);
}
public void WebRequestCallback(IAsyncResult result)
{
//Do whatever you need to do as a result of the web request, then call the callback.
if (_callback != null) callback();
}
}
In your code that wants to make a web request:
var helper = new WebRequestHelper();
//Setup the web request
object request = SetUpYourWebRequest();
helper.MakeWebRequest(request, OnWebRequestCompleted);
Your helper callback:
public void OnWebRequestCompleted()
{
//Web request is finished, what do I want to do?
}
Note that you might want your callback (which you pass to the WebRequestHelper object) to accept a parameter and you could pass information back out from the web request callback function (in the WebRequestHelper object).
Since your web download code is effectively your business logic I would definitely encapsulate it in it's own class as you planned. Then you should use events to notify your UI of state changes.
For example, your "WebRequestManager" instance can encapsulate all the thread handling and will raise events to allow the UI to respond accordingly. You would raise an event on TaskCompleted and perhaps also at intervals to provide looking feedback such as AsyncProgressChanged.
NOTE: By way of convention, I would tend to prefix any events that are likely going to be called from a thread other than the original calling one with the name "Async" so that the UI handler knows to join back onto the UI thread.