Autofac registration issue with MediatR - mediatr

I am having some issues with MediatR using AutoFac. My registration code is below which I have lifted and slightly modified from GitHub. The class EntityContext is within the main code assembly, and Assembly is set to that assembly:
var builder = new Autofac.ContainerBuilder();
builder.RegisterApiControllers(Assembly);
if (config != null)
{
builder.RegisterWebApiFilterProvider(config);
}
builder.RegisterSource(new ContravariantRegistrationSource());
builder.RegisterAssemblyTypes(typeof(EntityContextFactory).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(typeof(Ping).GetTypeInfo().Assembly).Where(t =>
t.GetInterfaces().Any(i => TypeExtensions.IsClosedTypeOf(i, typeof(IRequestHandler<,>))
|| TypeExtensions.IsClosedTypeOf(i, typeof(IAsyncRequestHandler<,>))
||
TypeExtensions.IsClosedTypeOf(i,
typeof(ICancellableAsyncRequestHandler<,>))
|| TypeExtensions.IsClosedTypeOf(i, typeof(INotificationHandler<>))
|| TypeExtensions.IsClosedTypeOf(i, typeof(IAsyncNotificationHandler<>))
||
TypeExtensions.IsClosedTypeOf(i,
typeof(ICancellableAsyncNotificationHandler<>))
)
)
.AsImplementedInterfaces();
builder.RegisterInstance(Console.Out).As<TextWriter>();
builder.Register<SingleInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t =>
{
object o;
return c.TryResolve(t, out o) ? o : null;
};
});
builder.Register<MultiInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
});
builder.RegisterConsumers(Assembly);
Container = builder.Build();
None of my IRequestHandler registrations are available for resolution using
using (var scope = container.BeginLifetimeScope())
{
scope.Resolve<AddTemplateHandler>();
}
An Explicit registration of the types above also does not work.
Can anyone help?

Related

Unable to cast object of type 'ServiceStack.OrmLite.OrmLiteDataParameter' to type 'Oracle.DataAccess.Client.OracleParameter'

I am using this code
using (var db = OpenDbConnection())
if (db != null)
db.Run(dbCnx =>
{
var trans = dbCnx.BeginTransaction();
dbCnx.UpdateOnly(new ProtectiveMarkingRequest
{
SecondApproverUserName = request.SecondApproverUserName,
Status = request.Status
},
onlyFields: p => new
{
p.SecondApproverUserName,
p.Status
},
#where: p => p.WorkItemCode == request.WorkItemCode);
}
trans.Commit();
});
After updating to servicestack.ormlite.oracle 4.0.52 (from 4.0.38) I receive the following error:
System.InvalidCastException was unhandled by user code
HResult=-2147467262
Message=Unable to cast object of type 'ServiceStack.OrmLite.OrmLiteDataParameter' to type 'Oracle.DataAccess.Client.OracleParameter'.
Source=Oracle.DataAccess
StackTrace:
at Oracle.DataAccess.Client.OracleParameterCollection.Add(Object obj)
at ServiceStack.OrmLite.DbDataParameterExtensions.AddParam(IOrmLiteDialectProvider dialectProvider, IDbCommand dbCmd, Object value, Type fieldType)
at ServiceStack.OrmLite.Oracle.OracleOrmLiteDialectProvider.PrepareUpdateRowStatement(IDbCommand dbCmd, Object objWithProperties, ICollection1 updateFields)
at ServiceStack.OrmLite.WriteExpressionCommandExtensions.UpdateOnlySql[T](IDbCommand dbCmd, T model, SqlExpression1 onlyFields)
at ServiceStack.OrmLite.WriteExpressionCommandExtensions.UpdateOnly[T](IDbCommand dbCmd, T model, SqlExpression1 onlyFields)
at ServiceStack.OrmLite.OrmLiteWriteExpressionsApi.<>c__DisplayClass72.b__6(IDbCommand dbCmd)
at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter)
at ECMAPI.Repository.Security.SecurityRepository.<>c__DisplayClassfb.b__f9(IDbConnection dbCnx) in SecurityRepository.cs:line 1970
Any clues?
To use Transaction Support in OrmLite you should use OpenTransaction() also the Run() extension method doesn't provide any value so I'd rewrite your example to just:
using (var db = OpenDbConnection())
using (var trans = db.OpenTransaction())
{
db.UpdateOnly(new ProtectiveMarkingRequest
{
SecondApproverUserName = request.SecondApproverUserName,
Status = request.Status
},
onlyFields: p => new {
p.SecondApproverUserName,
p.Status
},
#where: p => p.WorkItemCode == request.WorkItemCode);
}
trans.Commit();
}

LINQ query fails with nullable variable ormlite

I'm trying to write following LINQ query using ServiceStack Ormlite.
dbConn.Select<Product>(p => p.IsActive.HasValue && p.IsActive.Value)
Here, Product is my item class and "IsActive" is Nullable Bool property in that class. When this line executes it always throws "InvalidOperationException" with the message
variable 'p' of type '' referenced from scope '', but it is not defined
I tried different variants as following but still same exception result
dbConn.Select<Product>(p => p.IsActive.HasValue == true && p.IsActive.Value == true)
dbConn.Select<Product>(p => p.IsActive != null && p.IsActive.Value == true)
But if I just write
dbConn.Select<Product>(p => p.IsActive.HasValue)
then it works.
I'm puzzled what is the problem? Is this servicestack ormlite issue?
My answer can handle Nullable value like "value" and "HasValue" with servicestack ormlite. And But also with datetime nullable ,like 'createdate.value.Year'.
you must change two place.
modify VisitMemberAccess method:
protected virtual object VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null)
{
if (m.Member.DeclaringType.IsNullableType())
{
if (m.Member.Name == nameof(Nullable<bool>.Value))
return Visit(m.Expression);
if (m.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(m.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
throw new ArgumentException(string.Format("Expression '{0}' accesses unsupported property '{1}' of Nullable<T>", m, m.Member));
}
if (m.Member.DeclaringType == typeof(DateTime))
{
var ExpressionInfo = m.Expression as MemberExpression;
if (ExpressionInfo.Member.DeclaringType.IsNullableType())
{
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.Value))
{
var modelType = (ExpressionInfo.Expression as MemberExpression).Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = (ExpressionInfo.Expression as MemberExpression).Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
{
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
}
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(ExpressionInfo.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
}
else
{
var modelType = ExpressionInfo.Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = ExpressionInfo.Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
}
if (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)
{
var propertyInfo = (PropertyInfo)m.Member;
var modelType = m.Expression.Type;
if (m.Expression.NodeType == ExpressionType.Convert)
{
var unaryExpr = m.Expression as UnaryExpression;
if (unaryExpr != null)
{
modelType = unaryExpr.Operand.Type;
}
}
var tableDef = modelType.GetModelDefinition();
if (propertyInfo.PropertyType.IsEnum)
return new EnumMemberAccess(
GetQuotedColumnName(tableDef, m.Member.Name), propertyInfo.PropertyType);
return new PartialSqlString(GetQuotedColumnName(tableDef, m.Member.Name));
}
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
return getter();
}
modify VisitLambda method :
protected virtual object VisitLambda(LambdaExpression lambda)
{
if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ")
{
MemberExpression m = lambda.Body as MemberExpression;
if (m.Expression != null)
{
string r = VisitMemberAccess(m).ToString();
if (m.Member.DeclaringType.IsNullableType())
return r;
return string.Format("{0}={1}", r, GetQuotedTrueValue());
}
}
return Visit(lambda.Body);
}
This is nature of the Linq. In order to achieve what you need, you will need to use two where closes:
dbConn.Where<Product>(p => p.IsActive.HasValue).Where(p=>p.Value==true);

Use method in entity framework query

Is there anyway around this error? I'd like to reuse the same lamba expression in other queries instead of having duplication. Can LinqKit or other linq expression do this?
Error
LINQ to Entities does not recognize the method 'Boolean GetEvent(Tournaments.Data.Entities.Event, System.String)' method, and this method cannot be translated into a store expression.
Code
public MobileEventDetailModel GetDetails(string applicationId)
{
var #event = (from e in _eventsRepository.DataContext.Events.Include(q => q.Assets.Select(a => a.Asset))
where GetEvent(e, applicationId)
select new
{
e.Id,
e.EventParent.Name,
LogoId = (from a in e.Assets
where a.Type == EventAssetType.Logo
select a.AssetId).FirstOrDefault()
}).FirstOrDefault();
return new MobileEventDetailModel
{
Id = #event.Id,
Name = #event.Name,
Logo = string.Format("{0}{1}{2}", Config.BaseUrl, Config.ImagesPath, #event.LogoId)
};
}
public bool GetEvent(Event #event, string applicationId)
{
return #event.Active && #event.Visible && #event.MobileEventApplications.Any(m =>
m.MobileApplication.ApplicationId == applicationId &&
(!m.MobileApplication.ActivationLength.HasValue || EntityFunctions.AddDays(DateTime.Now, 1) < EntityFunctions.AddMonths(m.MobileApplication.DateActivated, m.MobileApplication.ActivationLength.Value)));
}
You need to use an Expression:
public MobileEventDetailModel GetDetails(string applicationId)
{
var event = _eventsRepository.DataContext.Events.Include(q => q.Assets.Select(a => a.Asset))
.Where(GetEvent(applicationId))
.Select(a => new
{
a.Id,
a.EventParent.Name,
LogoId = (from b in a.Assets
where b.Type == EventAssetType.Logo
select b.AssetId).FirstOrDefault()
}).FirstOrDefault();
return new MobileEventDetailModel
{
Id = event.Id,
Name = event.Name,
Logo = string.Format("{0}{1}{2}", Config.BaseUrl, Config.ImagesPath, event.LogoId)
};
}
public Expression<Func<Event, bool>> GetEvent(int applicationId)
{
return = a => a.Active
&& a.Visible
&& a.MobileEventApplications
.Any(m => m.MobileApplication.ApplicationId == applicationId
&& (!m.MobileApplication.ActivationLength.HasValue
|| EntityFunctions.AddDays(DateTime.Now, 1)
< EntityFunctions
.AddMonths(m.MobileApplication.DateActivated, m.MobileApplication.ActivationLength.Value)
)
);
}
Update: Sorry it was late the other night, the changed version is hopefully more what you were looking for.

LINQ select item from a list where string contains any of the search terms in a list -> refactor

I have list of Items, called Translations. I filter the translations based on a search term from a search box, currently it looks like this:
private static IList<Translation> FilterTranslationListOLD(string filter, IEnumerable<Translation> translationList)
{
filter = filter.ToLower();
if (!string.IsNullOrEmpty(filter))
{
return translationList
.Where(t => (t.Tag.Filename.ToLower().Contains(filter)
|| t.Tag.FilePath.ToLower().Contains(filter)
|| t.Tag.TagContent.ToLower().Contains(filter)
|| (t.Tag.SanitizedTagContent != null && t.Tag.SanitizedTagContent.ToLower().Contains(filter))
|| (t.TagTranslation != null && t.TagTranslation.ToLower().Contains(filter))
|| (t.SanitizedTranslation != null && t.SanitizedTranslation.ToLower().Contains(filter))))
.OrderBy(t => t.Tag.FilePath)
.ThenBy(t => t.Tag.Filename).ThenBy(t => t.Tag.Id).ToList();
}
return translationList.OrderByDescending(t => t.DateTranslated).ToList();
}
I've now introduced the ability to search with multiple keywords, like so:
private static IList<Translation> FilterTranslationList(string filter, IEnumerable<Translation> translationList)
{
filter = filter.ToLower();
var splitFilterTerms = filter.Split(',');
if (splitFilterTerms.Any(split=>!string.IsNullOrEmpty(split)))
{
var translationListResults = new List<Translation>();
foreach (var splitFilterTerm in splitFilterTerms)
{
translationListResults.AddRange(translationList
.Where(t => (t.Tag.Filename.ToLower().Contains(splitFilterTerm)
|| t.Tag.FilePath.ToLower().Contains(splitFilterTerm)
|| t.Tag.TagContent.ToLower().Contains(splitFilterTerm)
|| (t.Tag.SanitizedTagContent != null && t.Tag.SanitizedTagContent.ToLower().Contains(splitFilterTerm))
|| (t.TagTranslation != null && t.TagTranslation.ToLower().Contains(splitFilterTerm))
|| (t.SanitizedTranslation != null && t.SanitizedTranslation.ToLower().Contains(splitFilterTerm))))
.OrderBy(t => t.Tag.FilePath)
.ThenBy(t => t.Tag.Filename).ThenBy(t => t.Tag.Id).ToList());
}
return translationListResults;
}
return translationList.OrderByDescending(t => t.DateTranslated).ToList();
}
what I would like to know is, is there a nicer way of writing this? Whilst it works, it would be nice to know how to do it in all linq or reduce/refactor it a little (make it a little neater). Thanks in advance!
Try looking at SelectMany, which will help you flatten a sequence of sequences:
private static IList<Translation> FilterTranslationListOLD(string filter, IEnumerable<Translation> translationList)
{
filter = filter.ToLower();
var splitFilterTerms = filter.Split(',');
if (splitFilterTerms.Any(split=>!string.IsNullOrEmpty(split)))
{
return splitFilterTerms.SelectMany(f => translationList
.Where(t => (t.Tag.Filename.ToLower().Contains(f)
|| t.Tag.FilePath.ToLower().Contains(f)
|| t.Tag.TagContent.ToLower().Contains(f)
|| (t.Tag.SanitizedTagContent != null && t.Tag.SanitizedTagContent.ToLower().Contains(f))
|| (t.TagTranslation != null && t.TagTranslation.ToLower().Contains(f))
|| (t.SanitizedTranslation != null && t.SanitizedTranslation.ToLower().Contains(f))))
.OrderBy(t => t.Tag.FilePath)
.ThenBy(t => t.Tag.Filename).ThenBy(t => t.Tag.Id)).ToList();
}
return translationList.OrderByDescending(t => t.DateTranslated).ToList();
}
I haven't actually run this code. Here is the MSDN documentation of SelectMany.
The problem with the above code is that it displays in OR condition and not AND...
So if you have these items:
List<Car> Cars = new List<Car>();
Cars.Add(new Car(){Manufacturer="Mercedes Benz", Color="Blue"});
Cars.Add(new Car(){Manufacturer="Mercedes Benz", Color="Green"});
it will display both if the filter is "Mercedes Blue"
I used this code to show only the blue car:
string Filter = "Mercedes blue";
List<string> SplittedFilter = new List<string>(Filter.ToLowerInvariant().Split(' '));
List<Car> FilteredCars = Cars;
foreach (var item in SplittedFilter) {
FilteredCars = (from c in FilteredCars
where c.Manufacturer.ToLowerInvariant().Contains(item) || c.Color.ToLowerInvariant().Contains(item)
select c).ToList();
}
Source: http://www.groggyjava.tv/blog/?p=84

What is the scariest LINQ function you've seen?

While working on a personal project I wanted a simple service to extract items out of Outlook and host in WCF in a "RESTful" design. In the process I came up with this rather beastly class.
What other scary linq code have people have seen?
public IQueryable<_AppointmentItem> GetAppointments(DateTime date)
{
var dayFlag = (OlDaysOfWeek)(int)Math.Pow(2, (int)date.DayOfWeek);
return
OlDefaultFolders.olFolderCalendar.GetItems<_AppointmentItem>()
.Select(a => new
{
Appointment = a,
RecurrencePattern = a.IsRecurring ?
a.GetRecurrencePattern() : null
})
.Where(a =>
a.Appointment.Start.Date <= date &&
(
(a.RecurrencePattern == null &&
a.Appointment.End.Date >= date) ||
(
a.RecurrencePattern != null &&
(
(a.RecurrencePattern.DayOfMonth == 0 ||
a.RecurrencePattern.DayOfMonth == date.Day) &&
(a.RecurrencePattern.DayOfWeekMask == 0 ||
((a.RecurrencePattern.DayOfWeekMask &
dayFlag) != 0)) &&
(a.RecurrencePattern.MonthOfYear == 0 ||
a.RecurrencePattern.MonthOfYear == date.Month)
)
)
)
)
.Select(a => a.Appointment);
}
[OperationContract()]
[WebGet(
UriTemplate = "/appointments/{year}/{month}/{day}",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare
)]
[ContentType("text/xml")]
public XElement ListAppointments(string year, string month, string day)
{
try
{
int iYear, iMonth, iDay;
int.TryParse(year, out iYear);
int.TryParse(month, out iMonth);
int.TryParse(day, out iDay);
if (iYear == 0) iYear = DateTime.Now.Year;
if (iMonth == 0) iMonth = DateTime.Now.Month;
if (iDay == 0) iDay = DateTime.Now.Day;
var now = new DateTime(iYear, iMonth, iDay).Date; // DateTime.Now;
return GetAppointments(now).ToXml();
}
catch (System.Exception ex)
{
return new XElement("exception", ex.ToString());
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Office.Interop.Outlook;
namespace WhitedUS.ServiceModel.Office.Linq
{
public static class OutlookUtilities
{
public static IQueryable<T> GetItems<T>(
this OlDefaultFolders defaultFolderType)
{
return
new ApplicationClass()
.Session
.GetDefaultFolder(defaultFolderType)
.Items
.OfType<T>()
.AsQueryable();
}
public static XElement ToXml<T>(this IEnumerable<T> input)
{
if (input == null)
return null;
Type typ = typeof(T);
var root = XName.Get(typ.Name.Trim('_'));
return new XElement(root,
input
.Select(x => x.ToXml<T>())
.Where(x => x != null)
);
}
public static XElement ToXml<T>(this object input)
{
if (input == null)
return null;
Type typ = typeof(T);
var root = XName.Get(typ.Name.Trim('_'));
return new XElement(root,
typ.GetProperties()
.Where(p => p.PropertyType.IsValueType ||
p.PropertyType == typeof(string))
.Select(p => new { Prop = p, Getter = p.GetGetMethod() })
.Where(p => p.Getter != null)
.Select(p => new { Prop = p.Prop, Getter = p.Getter,
Params = p.Getter.GetParameters() })
.Where(p => (p.Params == null || p.Params.Count() <= 0))
.Select(p => new { Name = p.Prop.Name,
Value = p.Getter.Invoke(input, null) })
.Where(p => p.Value != null)
.Select(p => new XAttribute(XName.Get(p.Name), p.Value))
);
}
}
}
Also see: What is the worst abuse you’ve seen of LINQ syntax?
A fully LINQified RayTracer is pretty scary.
Actually, the scariest Linq query I ever saw was my first one. It was just familiar enough to make me think I understood it and just different enough to make me doubt that I really did.

Resources