How to setup Elsa with custom schema and table creation without entity framework - elsa-workflows

Need to change Schema for Elsa tables
Need to avoid DDL operation for Elsa hosting service so I want to create all required tables before starting Elsa
I tried to override ElsaContext, but I do not have a clear idea of the implementation. I tried the following:
public class SqlElsaContextFactory : IDesignTimeDbContextFactory<ElsaContext>
{
public ElsaContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddCommandLine(args)
.Build();
var dbContextBuilder = new DbContextOptionsBuilder();
var connectionString = configuration.GetConnectionString("Elsa");
dbContextBuilder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(typeof(Program).Assembly.FullName));
return new ElsaContextExtension(dbContextBuilder.Options);
}
}
public class ElsaContextExtension : ElsaContext
{
public ElsaContextExtension(DbContextOptions options) : base(options)
{
}
protected string _schema = "test";
public override string Schema => _schema;
}
But getting the below error:

You can inherit from ElsaContext and override what you need. Something like this:
public class WorkflowDbContext : ElsaContext, IDbContext
{
public bool ProxyCreationEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public bool AutoDetectChangesEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public WorkflowDbContext(string connectionString) : base(SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options)
{
}
}
Then you can generate the SQL scripts like this:
private string CreateDatabaseScript()
{
return this.Database.GetService<IRelationalDatabaseCreator>().GenerateCreateScript();
}
Then install the scripts like this:
public void Install()
{
var scriptsBatch = this.CreateDatabaseScript();
foreach (var script in scriptsBatch.Split("GO", StringSplitOptions.RemoveEmptyEntries))
{
this.Database.ExecuteSqlRaw(script);
}
}
So by calling this Install method you can generate the tables before starting Elsa.

Related

how to fix Error No DataBase Provider when Everything is okay

When I want to Insert A New Object into the db bellow Error Occured:
No database provider has been configured for this DbContext
Services:
private IConfiguration config;
public Startup(IConfiguration config) => this.config = config;
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkSqlServer().AddDbContext<DataContext>(options => options.UseSqlServer(config["ConnectionStrings:MainConnection"]));
services.AddMvc();
}
DataContext:
public class DataContext:DbContext
{
public DataContext() { }
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
public DbSet<Request> Request { get; set; }
public DbSet<AdminAccept> AdminAccept { get; set; }
public DbSet<Payment> Payment { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
base.OnConfiguring(builder);
}
}
Insert command :
public async Task <int> SaveToStorageAsync()
{
using (DataContext context=new DataContext())
{
context.Request.Add(this);
return await context.SaveChangesAsync();
}
}
however migrations and database created succefully
I solved it finally.
everything is okay but use of using expression cause an error.(I wonder why)
to solving it first of all I removed a using and declare a DataContext as parameter:
public async Task<int> SaveToStorageAsync(DataContext context)
{
context.Request.Add(this);
return await context.SaveChangesAsync();
}
after it initiate constructor in the main controller :
DataContext context;
public HomeController(DataContext context)
{
this.context = context;
}
and finally call function by sending context as a parameter.
hopped you used in your scenarios and good luck
Since you register the DataContext with the constructor receiving a DbContextOptions<DataContext> option.You also need to pass that when you create a DataContext
var optionsBuilder = new DbContextOptionsBuilder<DataContext >();
optionsBuilder.UseSqlServer("Your connection string");
using (DataContext context = new DataContext (optionsBuilder.Options))
{
context.Request.Add(this);
return await context.SaveChangesAsync();
}
I suggest that you could use dbContext by DI in controller which is a more recommended way in asp.net core:
public class StudentsController : Controller
{
private readonly DataContext _context;
public StudentsController(DataContext context)
{
_context = context;
}
public async Task <int> SaveToStorageAsync()
{
_context.Request.Add(this);
return await context.SaveChangesAsync();
}
}
The two ways are included in below link:
https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#configuring-dbcontextoptions

Database handler globally as Singleton pattern in xamarin forms

I am developing an application which have a local database for offline support. So I am using Sqlite.net.pcl plugin and its working fine for all Create, Insert, Update and Delete table for every class model.
But instead of creating a separate database activities like insert, get, update for each Model class, I tried to worked on singeton pattern of common database handler(DatabasHandler.cs).
This is my code which I tried to workout singleton pattern,
public void CreateTable<T>() where T : new()
{
var myClass = new T();
myDatabase.CreateTableAsync<T>().Wait();
}
I called this function from my EmployeeViewModel class like this;
App.Database.CreateTable<EmployeeModel>();
here EmployeeModel is a model class and its worked fine, also the above function is successfully created a Employee Table. Doing the same way I created rest of the Tables from each ViewModel like this;
App.Database.CreateTable<SalaryModel>(); // call from SalaryViewModel Page
App.Database.CreateTable<EmployeeAttendanceModel>(); // call from AttendanceViewModel Page
Next: So how can I insert and get all list items into DatabaseHandler.cs using same (Create Table)singleton pattern. My question is;
How should I create a method for Insert/Get/Update a list in DatabaseHandler.cs(Singleton class)?
How should I call those method(Insert/Get/Update) from its viewmodel?
Please help me,
Now I had a similar thing in my Old XF app this is how I implemented the Singleton this will also answer your first question:
How should I create a method for Insert/Get/Update a list in DatabaseHandler.cs(Singleton class)?
public class DatabaseHandler: IDisposable
{
private SQLiteConnection conn;
//public static string sqlpath;
private bool disposed = false;
private static readonly Lazy<DatabaseHandler> database = new Lazy<DatabaseHandler>(() => new DatabaseHandler());
private DatabaseHandler() { }
public static DatabaseHandler Database
{
get
{
return database.Value;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
Dispose();
}
disposed = true;
}
public bool InitDatabase()
{
var ifExist = true;
try
{
this.CreateDatabase();
ifExist = TableExists(nameof(LocationModel), conn);
if (!ifExist)
this.CreateTable<LocationModel>();
return true;
}
catch (Exception ex)
{
return false;
}
}
public static bool TableExists(String tableName, SQLiteConnection connection)
{
var cmd = connection.CreateCommand("SELECT name FROM sqlite_master WHERE type = 'table' AND name = #name", new object[] { tableName });
//cmd.CommandText = "SELECT * FROM sqlite_master WHERE type = 'table' AND name = #name";
//cmd.Parameters.Add("#name", DbType.String).Value = tableName;
string tabledata = cmd.ExecuteScalar<string>();
return (cmd.ExecuteScalar<string>() != null);
}
public SQLiteConnection GetConnection()
{
var sqliteFilename = "xamdblocal.db3";
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path)) File.Create(path);
//var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var conn = new SQLiteConnection(path);
// Return the database connection
return conn;
}
private bool CreateDatabase()
{
conn = GetConnection();
string str = conn.DatabasePath;
return true;
}
public bool CreateTable<T>()
where T : new()
{
conn.DropTable<T>();
conn.CreateTable<T>();
return true;
}
public bool InsertIntoTable<T>(T LoginData)
where T : new()
{
conn.Insert(LoginData);
return true;
}
public bool InsertBulkIntoTable<T>(IList<T> LoginData)
where T : class //new()
{
conn.InsertAll(LoginData);
return true;
}
public List<T> SelectDataFromTable<T>()
where T : new()
{
try
{
return conn.Table<T>().ToList();
}
catch (Exception ex)
{
return null;
}
}
public List<T> SelectTableDatafromQuery<T>(string query)
where T : new()
{
return conn.Query<T>(query, new object[] { })
.ToList();
}
public bool UpdateTableData<T>(string query)
where T : new()
{
conn.Query<T>(query);
return true;
}
public void UpdateTableData<T>(IEnumerable<T> query)
where T : new()
{
conn.UpdateAll(query);
}
public void UpdateTableData<T>(T query)
where T : new()
{
conn.Update(query);
}
public bool DeleteTableData<T>(T LoginData)
{
conn.Delete(LoginData);
return true;
}
public bool DeleteTableDataFromPrimaryKey<T>(object primaryKey)
{
conn.Delete(primaryKey);
return true;
}
public bool DeleteTableDataFromQuery<T>(string query)
where T : new()
{
conn.Query<T>(query);
return true;
}
}
How should I call those method(Insert/Get/Update) from its viewmodel? Please help me,
Now for Eg: you want to insert location's Lat Long in your local database where your local model looks something like this:
public class LocationModel
{
[AutoIncrement, PrimaryKey]
public int Id { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string Address { get; set; }
}
So first what you will do is create an instance of LocationModel something like this:
var locationModel = new LocationModel
{
Latitude = location.Latitude,
Longitude = location.Longitude
};
Then insert it something like this:
DatabaseHandler.Database.InsertIntoTable<LocationModel>(locationModel);
Also, do not forget to add the SQLiteNetExtensions in your project for Linq support.
Goodluck feel free to revert in case of queries

Merging multiple custom observables in RX

Trying to model a system sending out notifications from a number of publishers using RX.
I have two custom interfaces ITopicObservable and ITopicObserver to model the fact that the implementing classes will have other properties and methods apart from the IObservable and IObserver interfaces.
The problem I have is that my thinking is I should be able to add a number of observables together, merge them together and subscribe to an observer to provide updates from all merged observables. However the code with "the issue" comment throws an invalid cast exception.
The use case is a number of independent sensors each monitoring a temperature in a box for example that aggregate all their reports to one temperature report which is then subscribed to by a temperature health monitor.
What am I missing here? Or is there a better way to implement the scenario using RX?
Code below
using System;
using System.Reactive.Linq;
using System.Collections.Generic;
namespace test
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
var to = new TopicObserver ();
var s = new TopicObservable ("test");
var agg = new AggregatedTopicObservable ();
agg.Add (s);
agg.Subscribe (to);
}
}
public interface ITopicObservable<TType>:IObservable<TType>
{
string Name{get;}
}
public class TopicObservable:ITopicObservable<int>
{
public TopicObservable(string name)
{
Name = name;
}
#region IObservable implementation
public IDisposable Subscribe (IObserver<int> observer)
{
return null;
}
#endregion
#region ITopicObservable implementation
public string Name { get;private set;}
#endregion
}
public class AggregatedTopicObservable:ITopicObservable<int>
{
List<TopicObservable> _topics;
private ITopicObservable<int> _observable;
private IDisposable _disposable;
public AggregatedTopicObservable()
{
_topics = new List<TopicObservable>();
}
public void Add(ITopicObservable<int> observable)
{
_topics.Add ((TopicObservable)observable);
}
#region IObservable implementation
public IDisposable Subscribe (IObserver<int> observer)
{
_observable = (ITopicObservable<int>)_topics.Merge ();
_disposable = _observable.Subscribe(observer);
return _disposable;
}
#endregion
#region ITopicObservable implementation
public string Name { get;private set;}
#endregion
}
public interface ITopicObserver<TType>:IObserver<TType>
{
string Name{get;}
}
public class TopicObserver:ITopicObserver<int>
{
#region IObserver implementation
public void OnNext (int value)
{
Console.WriteLine ("next {0}", value);
}
public void OnError (Exception error)
{
Console.WriteLine ("error {0}", error.Message);
}
public void OnCompleted ()
{
Console.WriteLine ("finished");
}
#endregion
#region ITopicObserver implementation
public string Name { get;private set;}
#endregion
}
}
My first thought, is that you shouldn't implement IObservable<T>, you should compose it by exposing it as a property or the result of a method.
Second thought is that there are operators in Rx that excel at merging/aggregating multiple sequences together.
You should favor using those.
Third, which is similar to the first, you generally don't implement IObserver<T>, you just subscribe to the observable sequence and provide delegates for each call back (OnNext, OnError and OnComplete)
So your code basically is reduced to
Console.WriteLine("Hello World!");
var topic1 = TopicListener("test1");
var topic2 = TopicListener("test2");
topic1.Merge(topic2)
.Subscribe(
val => { Console.WriteLine("One of the topics published this value {0}", val);},
ex => { Console.WriteLine("One of the topics errored. Now the whole sequence is dead {0}", ex);},
() => {Console.WriteLine("All topics have completed.");});
Where TopicListener(string) is just a method that returns IObservable<T>.
The implementation of the TopicListener(string) method would most probably use Observable.Create.
It may help to see examples of mapping Rx over a Topic based messaging system.
There is an example of how you can layer Rx over TibRv topics here https://github.com/LeeCampbell/RxCookbook/blob/master/IO/Comms/TibRvSample.linq
The signature of the .Merge(...) operator that you're using is:
IObservable<TSource> Merge<TSource>(this IEnumerable<IObservable<TSource>> sources)
The actual type returned by this .Merge() is:
System.Reactive.Linq.ObservableImpl.Merge`1[System.Int32]
...so it should be fairly clear that calling (ITopicObservable<int>)_topics.Merge(); would fail.
Lee's advice not to implement either of IObservable<> or IObserver<> is the correct one. It leads to errors like the one above.
If you had to do something like this, I would do it this way:
public interface ITopic
{
string Name { get; }
}
public interface ITopicObservable<TType> : ITopic, IObservable<TType>
{ }
public interface ITopicSubject<TType> : ISubject<TType>, ITopicObservable<TType>
{ }
public interface ITopicObserver<TType> : ITopic, IObserver<TType>
{ }
public class Topic
{
public string Name { get; private set; }
public Topic(string name)
{
this.Name = name;
}
}
public class TopicSubject : Topic, ITopicSubject<int>
{
private Subject<int> _subject = new Subject<int>();
public TopicSubject(string name)
: base(name)
{ }
public IDisposable Subscribe(IObserver<int> observer)
{
return _subject.Subscribe(observer);
}
public void OnNext(int value)
{
_subject.OnNext(value);
}
public void OnError(Exception error)
{
_subject.OnError(error);
}
public void OnCompleted()
{
_subject.OnCompleted();
}
}
public class AggregatedTopicObservable : Topic, ITopicObservable<int>
{
List<ITopicObservable<int>> _topics = new List<ITopicObservable<int>>();
public AggregatedTopicObservable(string name)
: base(name)
{ }
public void Add(ITopicObservable<int> observable)
{
_topics.Add(observable);
}
public IDisposable Subscribe(IObserver<int> observer)
{
return _topics.Merge().Subscribe(observer);
}
}
public class TopicObserver : Topic, ITopicObserver<int>
{
private IObserver<int> _observer;
public TopicObserver(string name)
: base(name)
{
_observer =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
}
public void OnNext(int value)
{
_observer.OnNext(value);
}
public void OnError(Exception error)
{
_observer.OnError(error);
}
public void OnCompleted()
{
_observer.OnCompleted();
}
}
And run it with:
var to = new TopicObserver("watching");
var ts1 = new TopicSubject("topic 1");
var ts2 = new TopicSubject("topic 2");
var agg = new AggregatedTopicObservable("agg");
agg.Add(ts1);
agg.Add(ts2);
agg.Subscribe(to);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
Which gives:
next 42
next 1
finished
But apart from being able to give everything a name (which I'm not sure how it helps) you could always do this:
var to =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
var ts1 = new Subject<int>();
var ts2 = new Subject<int>();
var agg = new [] { ts1, ts2 }.Merge();
agg.Subscribe(to);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
Same output with no interfaces and classes.
There's even a more interesting way. Try this:
var to =
Observer
.Create<int>(
value => Console.WriteLine("next {0}", value),
error => Console.WriteLine("error {0}", error.Message),
() => Console.WriteLine("finished"));
var agg = new Subject<IObservable<int>>();
agg.Merge().Subscribe(to);
var ts1 = new Subject<int>();
var ts2 = new Subject<int>();
agg.OnNext(ts1);
agg.OnNext(ts2);
ts1.OnNext(42);
ts1.OnCompleted();
ts2.OnNext(1);
ts2.OnCompleted();
var ts3 = new Subject<int>();
agg.OnNext(ts3);
ts3.OnNext(99);
ts3.OnCompleted();
This produces:
next 42
next 1
next 99
It allows you to add new source observables after the merge!

Session not saved in ServiceStack

I want to use the session feature but without athentication.
I already added Plugins.Add(new SessionFeature()) to AppHost.cs and I have the following code
public class CustomService : Service
{
public CustomResponse Any(CustomRequest pRequest)
{
var CustomSession = base.Session.Get<CustomType>("MySession");//try to get the session
if (CustomSession == null)
{
//create a new session
CustomSession = new CustomType{MyId=1};
base.Session["MySession"] = CustomSession;
//base.Session.Set("MySession", CustomSession); //also tried this, to save the session.
this.SaveSession(CustomSession, new TimeSpan (0,20,0)); //Save the Session
}
}
}
The problem I'm having is that base.Session.Get<CustomType>("MySession") is always null.
Am I missing something on the implementation of sessions?
You will need to save your session using base.SaveSession(). See here near the bottom there is a section title 'Saving in Service'.
public class MyAppHost : AppHostBase
{
public MyAppHost() : base("MyService", typeof(CustomService).Assembly)
{
}
public override void Configure(Container container)
{
Plugins.Add(new SessionFeature());
}
}
public class CustomType : AuthUserSession
{
public int MyId { get; set; }
}
[Route("/CustomPath")]
public class CustomRequest
{
}
public class CustomResponse
{
}
public class CustomService : Service
{
public CustomResponse Any(CustomRequest pRequest)
{
var CustomSession = base.SessionAs<CustomType>();
if (CustomSession.MyId == 0)
{
CustomSession.MyId = 1;
this.SaveSession(CustomSession, new TimeSpan(0,20,0));
}
return new CustomResponse();
}
}
Update:
There is a Resharper issue with extension methods, see here, which seems to affect SaveSession().
Work Arounds:
ServiceExtensions.SaveSession(this, CustomSession); ReSharper may prompt to reformat and it will work.
Ctrl-Alt-space to reformat
RequestContext.Get<IHttpRequest>().SaveSession(CustomSession) can save the
session.

Trying to call code in my controller but getting Null Reference error

Don't want to over-complicate the issue, but I think I need to post all the code that's hooked into this error.
Using MvcMailer and introduced a separate Send mechanism (for use with Orchard CMS' own EMail).
The MvcMailer Code:
1) AskUsMailer.cs:
public class AskUsMailer : MailerBase, IAskUsMailer
{
public AskUsMailer()
: base()
{
//MasterName = "_Layout";
}
public virtual MvcMailMessage EMailAskUs(AskUsViewModel model)
{
var mailMessage = new MvcMailMessage { Subject = "Ask Us" };
ViewData.Model = model;
this.PopulateBody(mailMessage, viewName: "EMailAskUs");
return mailMessage;
}
}
2) IAskUsMailer.cs:
public interface IAskUsMailer : IDependency
{
MvcMailMessage EMailAskUs(AskUsViewModel model);
}
3) AskUsController.cs: (GETTING NULL REFERENCE ERROR BELOW)
[Themed]
public ActionResult Submitted()
{
//This is the new call (see new code below):
//Note: Debugging steps through eMailMessagingService,
//then shows the null reference error when continuing to
//SendAskUs
eMailMessagingService.SendAskUs(askUsData);
//Below is normal MvcMailer call:
//AskUsMailer.EMailAskUs(askUsData).Send();
return View(askUsData);
}
Note: askUsData is defined in a separate block in the controller:
private AskUsViewModel askUsData;
protected override void OnActionExecuting(ActionExecutingContext
filterContext)
{
var serialized = Request.Form["askUsData"];
if (serialized != null) //Form was posted containing serialized data
{
askUsData = (AskUsViewModel)new MvcSerializer().
Deserialize(serialized, SerializationMode.Signed);
TryUpdateModel(askUsData);
}
else
askUsData = (AskUsViewModel)TempData["askUsData"] ??
new AskUsViewModel();
TempData.Keep();
}
protected override void OnResultExecuted(ResultExecutedContext
filterContext)
{
if (filterContext.Result is RedirectToRouteResult)
TempData["askUsData"] = askUsData;
}
I did not know how to get my EMailMessagingService.cs (see below) call into the controller, so in a separate block in the controller I did this:
private IEMailMessagingService eMailMessagingService;
public AskUsController(IEMailMessagingService eMailMessagingService)
{
this.eMailMessagingService = eMailMessagingService;
}
I think this is part of my problem.
Now, the new code trying to hook into Orchard's EMail:
1) EMailMessagingServices.cs:
public class EMailMessagingService : IMessageManager
{
private IAskUsMailer askUsMailer;
private IOrchardServices orchardServices;
public EMailMessagingService(IAskUsMailer askUsMailer,
IOrchardServices orchardServices)
{
this.orchardServices = orchardServices;
this.askUsMailer = askUsMailer;
this.Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public void SendAskUs(AskUsViewModel model)
{
var messageAskUs = this.askUsMailer.EMailAskUs(model);
messageAskUs.To.Add("email#email.com");
//Don't need the following (setting up e-mails to send a copy anyway)
//messageAskUs.Bcc.Add(AdminEmail);
//messageAskUs.Subject = "blabla";
Send(messageAskUs);
}
....
}
The EMailMessagingService.cs also contains the Send method:
private void Send(MailMessage messageAskUs)
{
var smtpSettings = orchardServices.WorkContext.
CurrentSite.As<SmtpSettingsPart>();
// can't process emails if the Smtp settings have not yet been set
if (smtpSettings == null || !smtpSettings.IsValid())
{
Logger.Error("The SMTP Settings have not been set up.");
return;
}
using (var smtpClient = new SmtpClient(smtpSettings.Host,
smtpSettings.Port))
{
smtpClient.UseDefaultCredentials =
!smtpSettings.RequireCredentials;
if (!smtpClient.UseDefaultCredentials &&
!String.IsNullOrWhiteSpace(smtpSettings.UserName))
{
smtpClient.Credentials = new NetworkCredential
(smtpSettings.UserName, smtpSettings.Password);
}
if (messageAskUs.To.Count == 0)
{
Logger.Error("Recipient is missing an email address");
return;
}
smtpClient.EnableSsl = smtpSettings.EnableSsl;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
messageAskUs.From = new MailAddress(smtpSettings.Address);
messageAskUs.IsBodyHtml = messageAskUs.Body != null &&
messageAskUs.Body.Contains("<") &&
messageAskUs.Body.Contains(">");
try
{
smtpClient.Send(messageAskUs);
Logger.Debug("Message sent to {0} with subject: {1}",
messageAskUs.To[0].Address, messageAskUs.Subject);
}
catch (Exception e)
{
Logger.Error(e, "An unexpected error while sending
a message to {0} with subject: {1}",
messageAskUs.To[0].Address, messageAskUs.Subject);
}
}
}
Now, in EMailMessagingService.cs I was getting an error that things weren't being implemented, so I auto-generated the following (don't know if this is part of my error):
public void Send(Orchard.ContentManagement.Records.ContentItemRecord recipient, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public void Send(System.Collections.Generic.IEnumerable<Orchard.ContentManagement.Records.ContentItemRecord> recipients, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public void Send(System.Collections.Generic.IEnumerable<string> recipientAddresses, string type, string service, System.Collections.Generic.Dictionary<string, string> properties = null)
{
throw new NotImplementedException();
}
public bool HasChannels()
{
throw new NotImplementedException();
}
public System.Collections.Generic.IEnumerable<string> GetAvailableChannelServices()
{
throw new NotImplementedException();
}
2) IEMailMessagingServices.cs
public interface IEMailMessagingService
{
MailMessage SendAskUs(AskUsViewModel model);
}
MvcMailer works fine without this addition (outside of Orchard), but I am trying to get everything working within Orchard.
I just cannot figure out what I am doing wrong. Any thoughts?
Sorry for excessive code.
IEmailMessaginService does not implement IDependency, so it can't be found by Orchard as a dependency. That's why it's null.

Resources