Dependency Injection

Aug 24, 2016 at 12:04 PM
Why SQLDependency depends on concretions and not of abstrations? Why not use dependency injection or contract resolver to create instances incase of use of Activator?
Coordinator
Aug 24, 2016 at 12:10 PM
SqlTableDependency inherit from TableDependency class, that in turn, implement public interface ITableDependency<T> where T : class
Aug 25, 2016 at 7:18 AM
I'm sorry, I haven't explained well myself. I saw that you create instaces by calling "Activator.CreateInstance" on "RecordChangedEventArgs<T>" , so to is needed that "T" will be a concretion.
 // See code: 

namespace TableDependency.EventArgs
{
    public class RecordChangedEventArgs<T> : System.EventArgs where T : class
    {
        protected readonly IEnumerable<PropertyInfo> EntiyProperiesInfo;
        protected IEnumerable<ColumnInfo> UserInterestedColumns;

        #region Properties

        internal MessagesBag MessagesBag { get; }
        public T Entity { get; protected set; }
        public ChangeType ChangeType { get; protected set; }
        public string MessageType { get; protected set; }

        #endregion

        #region Constructors

        internal RecordChangedEventArgs(MessagesBag messagesBag, ModelToTableMapper<T> mapper, IEnumerable<ColumnInfo> userInterestedColumns)
        {
            this.MessagesBag = messagesBag;
            this.EntiyProperiesInfo = ModelUtil.GetModelPropertiesInfo<T>();
            this.UserInterestedColumns = userInterestedColumns;

            ChangeType = messagesBag.MessageType;
            Entity = MaterializeEntity(messagesBag.MessageSheets, mapper);
        }

        #endregion

        #region Internal methods

        internal virtual T MaterializeEntity(List<Message> messages, ModelToTableMapper<T> mapper)
        {
            var entity = (T)Activator.CreateInstance(typeof(T));  // This is what i said. Maybe is important that we could say to a mapper how resolve instance.

            foreach (var entityPropertyInfo in this.EntiyProperiesInfo)
            {
                var propertyMappedTo = mapper?.GetMapping(entityPropertyInfo);
                var columnName = propertyMappedTo ?? entityPropertyInfo.Name;

                var message = messages.FirstOrDefault(m => string.Equals(m.Recipient, columnName, StringComparison.CurrentCultureIgnoreCase));
                if (message == default(Message)) continue;

                var dbColumnInfo = this.GetColumnInfo(columnName);

                var value = GetValue(entityPropertyInfo, dbColumnInfo, message.Body);
                entityPropertyInfo.SetValue(entity, value);
            }

            return entity;
        }

        internal virtual ColumnInfo GetColumnInfo(string columnName)
        {
            return this.UserInterestedColumns.First(uic => string.Equals(uic.Name, columnName, StringComparison.CurrentCultureIgnoreCase));
        }

        internal virtual object GetValue(PropertyInfo entityPropertyInfo, ColumnInfo columnInfo, byte[] message)
        {
            var formatCulture = new CultureInfo("en-US", false);
            var stringValue = this.MessagesBag.Encoding.GetString(message).ToString(formatCulture);
            var typeDescriptor = TypeDescriptor.GetConverter(entityPropertyInfo.PropertyType);
            var result = typeDescriptor.ConvertFromString(null, formatCulture, stringValue);
            return result;
        }

        #endregion
    }
}